zoukankan      html  css  js  c++  java
  • 表的外健(foreign key)

    foreign key(表与表之间的关系)

    引子

    把所有的数据存在一张表的弊端:
    1、表的组织结构复杂不清晰
    2、浪费空间
    3、扩展性极差

    语法示例

     1#表类型必须是innodb存储引擎,且被关联的字段,即references指定的另外一个表的字段,必须保证唯一
    2create table department(
    3id int primary key,
    4name varchar(20) not null
    5)engine=innodb;
    6
    7#dpt_id外键,关联父表(department主键id),同步更新,同步删除
    8create table employee(
    9id int primary key,
    10name varchar(20) not null,
    11dpt_id int,
    12constraint fk_name foreign key(dpt_id)
    13references department(id)
    14on delete cascade
    15on update cascade
    16)engine=innodb;
    17
    18#先往父表department中插入记录
    19insert into department values
    20(1,'欧德博爱技术有限事业部'),
    21(2,'艾利克斯人力资源部'),
    22(3,'销售部');
    23
    24#再往子表employee中插入记录
    25insert into employee values
    26(1,'egon',1),
    27(2,'alex1',2),
    28(3,'alex2',2),
    29(4,'alex3',2),
    30;
    31
    32#删父表department,子表employee中对应的记录跟着删
    33mysql> delete from department where id=3;
    34mysql> select * from employee;
    35+----+-------+--------+
    36| id | name | dpt_id |
    37+----+-------+--------+
    38| 1 | egon | 1 |
    39| 2 | alex1 | 2 |
    40| 3 | alex2 | 2 |
    41| 4 | alex3 | 2 |
    42+----+-------+--------+
    43
    44#更新父表department,子表employee中对应的记录跟着改
    45mysql> update department set id=22222 where id=2;
    46mysql> select * from employee;
    47+----+-------+--------+
    48| id | name | dpt_id |
    49+----+-------+--------+
    50| 1 | egon | 1 |
    51| 3 | alex2 | 22222 |
    52| 4 | alex3 | 22222 |
    53| 5 | alex1 | 22222 |
    54+----+-------+--------+

    foreign key会带来什么样的效果?

    约束1:在创建表时,先建被关联的表,才能建关联表
    约束2:在插入记录时,必须先给被关联的表插入记录,才能给关联表插入记录
    约束3:更新与删除都需要考虑到关联与被关联的关系
    约束3的解决方案:同步更新 on update cascade 同步删除on delete cascade

    如何找出表之间的关系

     1>分析步骤:
    2**1、先站在左表的角度去找**
    3是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
    4**2、再站在右表的角度去找**
    5是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
    6**3、总结:**
    7#多对一:
    8如果只有步骤1成立,则是左表多对一右表
    9如果只有步骤2成立,则是右表多对一左表
    10#多对多
    11如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系
    12#一对一:
    13如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可

    建立表之间的关系
    一对多或者多对一

    三张表:出版社,作者信息,书
    一对多(或多对一):一个出版社可以出版多本书
    关联方式:foreign key

     1=====================多对一=====================
    2create table press(
    3id int primary key auto_increment,
    4name varchar(20)
    5);
    6
    7create table book(
    8id int primary key auto_increment,
    9name varchar(20),
    10press_id int not null,
    11foreign key(press_id) references press(id)
    12on delete cascade
    13on update cascade
    14);
    15
    16insert into press(name) values
    17('北京工业地雷出版社'),
    18('人民音乐不好听出版社'),
    19('知识产权没有用出版社')
    20;
    21
    22insert into book(name,press_id) values
    23('九阳神功',1),
    24('九阴真经',2),
    25('九阴白骨爪',2),
    26('独孤九剑',3),
    27('降龙十巴掌',2),
    28('葵花宝典',3)
    29;

    多对多

    三张表:出版社,作者信息,书
    多对多:一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
    关联方式:foreign key+一张新的表

     1====================多对多=====================
    2create table author(
    3id int primary key auto_increment,
    4name varchar(20)
    5);
    6
    7#这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
    8create table author2book(
    9id int not null unique auto_increment,
    10author_id int not null,
    11book_id int not null,
    12constraint fk_author foreign key(author_id) references author(id)
    13on delete cascade
    14on update cascade,
    15constraint fk_book foreign key(book_id) references book(id)
    16on delete cascade
    17on update cascade,
    18primary key(author_id,book_id)
    19);
    20
    21#插入四个作者,id依次排开
    22insert into author(name) values('egon'),('alex'),('yuanhao'),('wpq');
    23
    24#每个作者与自己的代表作如下
    251 egon:
    26 1 九阳神功
    27 2 九阴真经
    28 3 九阴白骨爪
    29 4 独孤九剑
    30 5 降龙十巴掌
    31 6 葵花宝典
    322 alex:
    33 1 九阳神功
    34 6 葵花宝典
    353 yuanhao:
    36 4 独孤九剑
    37 5 降龙十巴掌
    38 6 葵花宝典
    394 wpq:
    40 1 九阳神功
    41
    42insert into author2book(author_id,book_id) values
    43(1,1),
    44(1,2),
    45(1,3),
    46(1,4),
    47(1,5),
    48(1,6),
    49(2,1),
    50(2,6),
    51(3,4),
    52(3,5),
    53(3,6),
    54(4,1)
    55;

    一对一

    两张表:学生表和客户表
    一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系
    关联方式:foreign key+unique

     1#一定是student来foreign key表customer,这样就保证了:
    2#1 学生一定是一个客户,
    3#2 客户不一定是学生,但有可能成为一个学生
    4
    5create table customer(
    6id int primary key auto_increment,
    7name varchar(20) not null,
    8qq varchar(10) not null,
    9phone char(16) not null
    10);
    11
    12create table student(
    13id int primary key auto_increment,
    14class_name varchar(20) not null,
    15customer_id int unique, #该字段一定要是唯一的
    16foreign key(customer_id) references customer(id) #外键的字段一定要保证unique
    17on delete cascade
    18on update cascade
    19);
    20
    21#增加客户
    22insert into customer(name,qq,phone) values
    23('李飞机','31811231',13811341220),
    24('王大炮','123123123',15213146809),
    25('守榴弹','283818181',1867141331),
    26('吴坦克','283818181',1851143312),
    27('赢火箭','888818181',1861243314),
    28('战地雷','112312312',18811431230)
    29;
    30
    31#增加学生
    32insert into student(class_name,customer_id) values
    33('脱产3班',3),
    34('周末19期',4),
    35('周末19期',5)
    36;

    表的其他操作

    修改

     1语法:
    21. 修改表名
    3 ALTER TABLE 表名
    4 RENAME 新表名;
    52. 增加字段
    6 ALTER TABLE 表名
    7 ADD 字段名 数据类型 [完整性约束条件…],
    8 ADD 字段名 数据类型 [完整性约束条件…];
    9 ALTER TABLE 表名
    10 ADD 字段名 数据类型 [完整性约束条件…] FIRST;
    11 ALTER TABLE 表名
    12 ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;
    13
    143. 删除字段
    15 ALTER TABLE 表名
    16 DROP 字段名;
    17
    184. 修改字段
    19 ALTER TABLE 表名
    20 MODIFY 字段名 数据类型 [完整性约束条件…];
    21 ALTER TABLE 表名
    22 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
    23 ALTER TABLE 表名
    24 CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

    示例

     11. 修改存储引擎
    2mysql> alter table service
    3 -> engine=innodb;
    4
    52. 添加字段
    6mysql> alter table student10
    7 -> add name varchar(20) not null,
    8 -> add age int(3) not null default 22;
    9
    10mysql> alter table student10
    11 -> add stu_num varchar(10) not null after name; //添加name字段之后
    12
    13mysql> alter table student10
    14 -> add sex enum('male','female') default 'male' first; //添加到最前面
    15
    163. 删除字段
    17mysql> alter table student10
    18 -> drop sex;
    19
    20mysql> alter table service
    21 -> drop mac;
    22
    234. 修改字段类型modify
    24mysql> alter table student10
    25 -> modify age int(3);
    26mysql> alter table student10
    27 -> modify id int(11) not null primary key auto_increment; //修改为主键
    28
    295. 增加约束(针对已有的主键增加auto_increment)
    30mysql> alter table student10 modify id int(11) not null primary key auto_increment;
    31ERROR 1068 (42000): Multiple primary key defined
    32
    33mysql> alter table student10 modify id int(11) not null auto_increment;
    34Query OK, 0 rows affected (0.01 sec)
    35Records: 0 Duplicates: 0 Warnings: 0
    36
    376. 对已经存在的表增加复合主键
    38mysql> alter table service2
    39 -> add primary key(host_ip,port);
    40
    417. 增加主键
    42mysql> alter table student1
    43 -> modify name varchar(10) not null primary key;
    44
    458. 增加主键和自动增长
    46mysql> alter table student1
    47 -> modify id int not null primary key auto_increment;
    48
    499. 删除主键
    50a. 删除自增约束
    51mysql> alter table student10 modify id int(11) not null;
    52
    53b. 删除主键
    54mysql> alter table student10
    55 -> drop primary key;

    复制

     1#复制表结构+记录 (key不会复制: 主键、外键和索引)
    2mysql> create table new_service select * from service;
    3
    4#只复制表结构
    5mysql> select * from service where 1=2; //条件为假,查不到任何记录
    6Empty set (0.00 sec)
    7mysql> create table new1_service select * from service where 1=2;
    8Query OK, 0 rows affected (0.00 sec)
    9Records: 0 Duplicates: 0 Warnings: 0
    10
    11mysql> create table t4 like employees;

    删除

    1DROP TABLE 表名;
    2#补充
    3delete from tb1;
    4强调:上面的这条命令确实可以将表里的所有记录都删掉,但不会将id重置为0,
    5所以该条命令根本不是用来清空表的,delete是用来删除表中某一些符合条件的记录,
    6如:delete from tb1 where id > 10;
    7如果要清空表,使用truncate tb1;
    8作用:将整张表重置
  • 相关阅读:
    oracle 11g行转列 列转行
    System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
    ORA-00257: 归档程序错误。在释放之前仅限于内部连接
    java 回传参数
    Oracle 删除表分区
    Oracle 删除重复数据只留一条
    cmd下windows批处理,获取当前系统时间,生成日志文件名
    c# 应用程序部署发布
    eclipse 集成 STS 插件
    Mamen所需要的jar包怎么生成
  • 原文地址:https://www.cnblogs.com/guodengjian/p/9014536.html
Copyright © 2011-2022 走看看