数据库3 待改

1.多表关联
在日常开发中 如果性能要求比较高 不应该使用外键
1.效率降低
2,耦合问题 关联起来后管理麻烦
这个时候 关系只是逻辑关系 很有可能产生错误数据

为什么要分表?
1.有重复数据 浪费空间
2.数据结构混乱
3.扩展性、维护性差
需要分表:
create table dept(id int primary key auto_increment,name char(20),job char(20));
create table emp(id int primary key auto_increment,name char(20),gendr char,age int,salary float,d_id int)

以上代码 可以建立关联关系 但是这个关系是逻辑上的 不实际存在
需要为他建立物理上的关联
通过外键 约束
create table 表名(字段名 类型(长度),foreign key(外键的字段名称) references 对方表名(对方主键名))
使用外键关系时 必须分清主从关系
1.外键的第一种约束:
先建主表
再建从表

2.外键的第二个约束:
先插入主表
再插入从表

3.外键的第三个约束:
删除记录时
先删除从表记录
再删除主表记录

4.外键的第四个约束:
从表更新外键时 必须保证主表是存在的

5.外键的第五个约束:
更新主表的id时
必须先删除从表关联的数据
或者把关联的数据 关联到其他的主表id

6.外键的第六个约束:
删除主表时
先删除从表
再删除主表

有了这几个约束后 主表和从表的数据必然是完整的

相应的受到外键的约束 主表的删除更新操作收到限制
很多情况下就是要删除一个部门 然而需要至少两条sql语句 繁琐
可以使用级联
create table emp(
id int primary key auto_increment,
name char(20),
d_id int,
foreign key(d_id) references dept(id)
on delete cascade #当主表删除记录时 从表关联记录同步删除
on update cascade #当主表id更新是 从表相关关联的记录同步更新
);
注意是单项的 主表变化是级联操作从表 从表变化是不会关联到主表的



多对多 其实就是双向的多对一
只要遇到多对多关系 就建立一个专门存放关系的中间表

例子:
老师和学生
一个老师可以教多个学生
一个学生可以被多个老师教

如何知道? 1号老师教过哪些学生
1号学生被哪些老师教过

老师表和学生表
需要一个中间表 专门存储关联关系

create table teacher(id int primary key auto_increment,name char(15));
create table student(id int primary key auto_increment,name char(15));
中间表:
create table tsr(
id int primary key auto_increment,
t_id int,s_id int,
foreign key(t_id) references teacher(id),
foreign key(s_id) references student(id)
);

现在老师和学生都是主表 关系表是从表
先插入老师和学生数据
insert into teacher values(1,"高跟"),(2,"艾根");
insert into student values(1,"张三"),(2,"李四");
#插入对应关系
insert into student values(null,1,1),(null,1,2),(null,2,2);



一对一关系加个外键即可:
注意 :一对一中外键的值不允许重复
夫妻关系确实是一对一的 但是在表中字段完全相同 没有必要分表
强行举例:
客户 和 学生
一个客户产生一个学生
一个学生只能对应一个客户
这样的关系是一对一
使用外键来关联 但是需要给外键加上唯一的约束
客户和学生有主从关系 需要先建立客户 再建学生
create table customer(
c_id int primary key auto_increment,
name char(20),
phonenum char(11),
addr char(20)
);

create table student(
s_id int primary key auto_increment,
name char(20),
class char(11),
number char(20),
housenum char(20),
foreign key(c_id) references ccustomer(c_id),
);

一对一的另一种使用场景
当一个表这种字段太多 而查用字段不多时 可以采用垂直分表的方式来提高效率
原有的person表
身份证号 姓名 性别 年龄 地址 民族 身高 血型 体重 学历 政治面貌 联系方式

拆分为:
st_info
姓名 性别 年龄

details_info
身份证号 地址 民族 身高 血型 体重 学历 政治面貌 联系方式



也有另一种提升效率的方式 水平分表
当一个表中数据记录太多时 效率会降低 可以采取水平分表 字段完全相同
stu 中有十万数据
stu1 五万
stu2 五万


什么时候要分表?
当一条记录中的数据 不属于同一类时

分表后产生的问题:
员工表中可以存储一个不存在的部门编号,这样的数据是不完整的 无效数据
必须找到一种方法,可以在物理层面建立关联关系。
解决方案:外键约束。

外键是维护表与表之间的关系
表之间的关系到底是什么样的:
1.要站先站在员工的角度思考 多个员工是否可以属于同一个部门 可以 员工对部门(多对一)
2.然后站在部门的角度来思考 多个部门能否同时包含一个员工 不可以 站在部门的角度 一个
员工只能属于一个部门 所以一对一的关系
3.最后 综合两个表之间的关系 如果两边都是多对一 则称之为双向多对一 其实就是多对多
如果两边只有一方是多对一 则称之为单项多对一

表之间的关系
一对多
多对多
一对一

外键的使用
FOREING KEY

级联操作
CASCADE





表的操作:

1.修改表
add 添加字段 adter|first
after 添加字段到哪个字段后面
first 添加字段到最前面
modify 修改字段类型
change 修改字段名称 或 类型
drop 删除字段
rename 改表名



2.复制表
create table 新的表名 select *from 原表名;
数据
结构
约束 不能复制
当条件不成立时 只复制表结构
create table 新的表名 select *from 原表名 where 1=2;
select *from 原表名 where 1=2



3.蠕虫复制
自我复制:
insert into 表名称 select *from 表明名;
如果有主键 避开主键字段
insert into 表名称(其他字段)select name from 表名;

sql注入攻击
一个了解sq语法的攻击者 可以在输入框输入sql语句
例如: 用户名22345678765432 密码12345
正常状态:select *from user where account = "22345678765432"and pwd ="12345";
被攻击:select *from user where account = ":"drop database mysql"and pwd ="12345";

猜你喜欢

转载自www.cnblogs.com/yanhui1995/p/9994354.html