SQL练习之不破坏应用程序现有查询的修改模式
当我还是一个菜鸟的时候,当然现在也是,当我的软件需求发生变化时,并且数据库设计同样要求发生变化,我通常会放弃原有的代码(或者对原有的代码进行大改),先在我知道了两个不破坏应用程序现有查询的修改模式,下面就来一个个介绍!
假设你的公司有一张记录在数据库中的设备登记表:
资产标识 描述 收到日期
50430 桌面PC 2016-5-6
50431 19寸监视器 2016-5-7
现在公司再融资之后,进行了扩张,在另一个地方又建立了新的办公室,这个时候如果简单的复制并修改原先的应用和数据库,并且在两个位置独立运行的实例是一种诱人的做法(说简单点就是再建一个用于维护新办公室信息的页面),然后这种做法虽然快速地解决了当前的问题,但是从长远的角度看会引起跟多的问题,这样我们有两个应用程序需要维护(并且这两个应用程序在功能上基本接近),所以这种方法不具有伸缩性,并且随着办公室的增加会使问题变得更加糟糕!
下面是分析列子所需的sql文件:
CREATE TABLE Equipment(
AssetTag varchar(30) not null,
Description varchar(255) null,
RequiredDate datetime null
)
INSERT INTO Equipment VALUES('50430','桌面PC',GETDATE())
INSERT INTO Equipment VALUES('50431','19寸监视器',GETDATE())
代码如下:
SELECT *
FROM Equipment
1、通过修改表的方式完成不破坏应用程序现有查询的修改模式 代码如下:
ALTER TABLE Equipment ADD Office varchar(30) null
UPDATE Equipment
SET Office='Headquarter'
SELECT *
FROM Equipment
这个时候,在表中添加一个新列Office,并且将现在设备表中的每一行数据都被赋值给了现在的办公室。
但是这一点都不符合大多数的实际情况,大所属情况可能是,我们将老办公室的一部分设备(用不到了的)搬到新办公室,然后老办公室被提升为总部(负责管理),这个时候只能手动去修改哪些已经被转移的设备到新的办公室!
现在我们可以插入新办公室的数据行了。然而这个时候问题又来了,原先依赖与这个表的所有查询都需要被重新检查。没有指定列的INSERT操作都会执行失败。因此,如果原来的INSERT语句为:
INSERT INTO Equipment VALUES('50431','19寸监视器',GETDATE())
DBMS会报错:列名或所提供值的数目与表定义不匹配。
但是,如果语句是:
INSERT INTO Equipment(AssetTag,Description,RequiredDate) VALUES('50430','桌面PC',GETDATE())
那么这句INSERT将会执行成功,NULL值将会被输入Office列。
可以看到,即使表以及被修改,还能是原先的查询正常的工作,但是他们会返回来自两个办公数的数据,即使我们只希望返回一个办公室的数据!
2、第二种模式通过代替表的视图来完成不破坏应用程序现有查询的修改模式
另一种方式是把现有的设备数据复制到新设计的设备表中,然后将新表中的每一行数据都归为老办公室的,如果设备有移动,那就做相应数据的更改,代码如下:
CREATE TABLE EquipmentMultiSite(
AssetTag varchar(30) not null,
Description varchar(255) null,
RequiredDate datetime null,
Office varchar(30) null
)
INSERT
INTO EquipmentMultiSite
SELECT Equipment.*,'Headquarter'
FROM Equipment
SELECT *
FROM EquipmentMultiSite
这里如果如果设备有移动,那就做相应数据的更改!修改之后的数据就是老办公室的设备数据!
现在就可以删除Equipment表,并用一个同名的Equipment视图来替换!
DROP TABLE Equipment
go
CREATE VIEW Equipment AS
SELECT AssetTag,Description,RequiredDate
FROM EquipmentMultiSite
WHERE Office='Headquarter'
go
这个时候,你会发现应用程序现有的查询,依然能够正常的工作,原先的办公室使用Equipment,不在乎他使用的是表还是视图,老办公室的经理现在应该能够继续利用该数据库的应用程序,但是他仅能操作(增删查该)老办公室的有关的设备。
但是对于新办公室的经理,你还需要做一些工作,你要确保Equipment关联每一个用户,这样的话,你就能为每一个用户以硬编码的方式指定正确的办公室!
- MySQL中的change,modify和自增列的关系(r12笔记第70天)
- Golang 值得注意的地方
- MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)
- WordPress评论滑动/拉链解锁myQaptcha修改为自动提交的方法
- MySQL root用户登录的几个小问题(r12笔记第67天)
- Java实现生产者消费者的两种方式(r12笔记第66天)
- Golang语言的函数调用信息
- mysqldump的一点使用总结(r12笔记第81天)
- 转-Golang语言Interface漫谈
- WordPress导航菜单图标字体插件font awesome 4 menus纯代码版
- Oracle 12c远程克隆PDB的问题及修复(r12笔记第78天)
- Oracle表中含有255列以上时需要注意的(r12笔记第77天)
- Golang语言--资源自动回收技术
- Oracle 12.2中的一个参数说明(r12笔记第76天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP设计模式之简单工厂和工厂模式实例分析
- PHP实现数据四舍五入的方法小结【4种方法】
- 如何在Windows中安装多个python解释器
- PHP设计模式之抽象工厂模式实例分析
- 使用python matploblib库绘制准确率,损失率折线图
- Django REST Swagger实现指定api参数
- matplotlib.pyplot.matshow 矩阵可视化实例
- php+mysql开发的最简单在线题库(在线做题系统)完整案例
- python中元组的用法整理
- PHP错误提示It is not safe to rely on the system……的解决方法
- PHP使用mysqli同时执行多条sql查询语句的实例
- 在tensorflow下利用plt画论文中loss,acc等曲线图实例
- PHP生成短网址的思路以及实现方法的详解
- ThinkPHP 3.2.3实现加减乘除图片验证码
- Python数据相关系数矩阵和热力图轻松实现教程