编辑1:最后的故事示例
几年前,我们创建了表格,以计算包装盒中有多少种产品。
有两个简单的表:
product (
code VARCHAR(16) PK,
length INT,
width INT,
height INT
)
box (
pkid INT IDENTITY(1,1),
barcode varchar(18),
product_code VARCHAR(16) FK,
quantity INT
)
还有两个相关的类:
public struct Product
{
public string Code { get; set; }
public int Length { get; set; }
public int Width { get; set; }
public int Heigth { get; set; }
}
public struct Box
{
public int Id { get; set; }
public string BarCode { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
}
多年后,我们需要将多个不同的产品放在同一个盒子中,所以现在我们需要这样做:
product (
code VARCHAR(16) PK,
length INT,
width INT,
height INT
)
-- box changed
box (
pkid INT IDENTITY(1,1),
barcode varchar(18)
)
-- stock created
stock (
box_pkid INT M-PK FK,
product_code VARCHAR(16) M-PK FK,
quantity INT
)
这:
public struct Product
{
public string Code { get; set; }
public int Length { get; set; }
public int Width { get; set; }
public int Heigth { get; set; }
}
public struct Box
{
public int Id { get; set; }
public string BarCode { get; set; }
public Dictionary<Product, int> Content { get; set; } // <-- this changed
public int Quantity { get; set; }
}
但是几年后,我们留下了很多代码,也许在某些黑暗的地方有重复的代码,这些代码是由合作者留下的。我是一名实习生,所以我希望获得未来的经验,以便以后避免这种情况。
什么是更新我们的架构并保持数据完整性安全的解决方案?即使在数据库中有数百万行?
示例: 2014年,我们需要将10本书 Romeo和Juliet 放在一个盒子里。如果我们有一些 Hamlet 书籍,则将它们放在另一个盒子中。 Romeo和Juliet 的所有10本书都是“相同”的产品(封面相同,内容相同,参考文献相同)。
今天,我们想将不同的 Shakespear 书籍存储在同一盒子中。或不同的 Love 书。甚至还有《罗密欧与朱丽叶》和小雕像?如此不同的产品在一起:我们应该更改box table
和Box class
,不是吗?
答案 0 :(得分:1)
您面临许多挑战;我将它们分为两个高级小组。
首先,如何在代码级别更改应用程序,其次,如何将数据从旧模式迁移到新模式。
第一个问题是:您能否100%确定列出的类是访问和修改数据的唯一方法?是否有任何触发器,存储过程,批处理作业或其他应用程序?除了通过拖曳数据库架构工件和代码库之外,我不知道有什么方法可以找到答案。
在“自己的”应用程序中,您可以选择。通常,扩展比修改界面要好。实际上,这意味着不用更改公共Product Product { get; set; }
签名来处理字典,而是保留它并添加public Dictionary<Product, int> Content { get; set; }
-如果可以保证旧方法仍然有效。这意味着有限地重写类的所有依赖项-您只需要担心客户端需要了解一个盒子中可能有不止一种产品。
这使您可以遵循“许多小的更改,但是现有代码仍可以工作”的模型;您可以通过功能切换等方式进行管理。风险要低得多-因此,这里的课程是“为be open to extension, but closed to change设计解决方案”。
在这种情况下,似乎不太可能-“设置”方法可能还可以(您可以默认将其设置为“盒中一个产品”的解决方案),但是“获取”方法将无法正常使用盒子里有不止一种产品的情况下的处理方法。如果是这样,则可以更改类,并查找代码无法编译的所有实例,并遵循依赖关系链。
例如,在典型的MVC框架中,在这种情况下,您将更改模型;这将导致控制器报告编译错误。解决该错误时,几乎可以肯定地修改了控制器方法的签名。反过来这应该会破坏视图。因此,您遵循该链条;这样做意味着您的架构更改将成为“大爆炸,全有或全无”版本。这通常会给所有参与者带来压力...
这在很大程度上取决于您选择的两个选项中的哪个。 @gburton的答案涵盖了数据库步骤;这两个代码选项都是必需的。
第二个挑战是发布软件的新版本。例如,如果它是桌面客户端,则必须确保在更改数据库的同时更新所有客户端。 (通常)这太可怕了。如果是Web应用程序,通常会更简单-更少需要担心的客户端计算机。
答案 1 :(得分:0)
安全更新旧系统是一个经典问题。我从您的帖子中猜测,没有一个很好的数据库安全开发副本,或者至少有一个最新的数据库,或者您已经有一个流程可以在这里申请。
即使您显然使用的是MS SQL Server,我也已经以系统不可知的方式编写了此文件。
关键是要谨慎使用,并确保在发生问题时永远不会被100%卡住。
如果第5步显示一些错误,则只需解决这些错误。完成此操作后,您就会感到恐惧。备份还原演练在这里至关重要。
使用许多数据库引擎可以恢复到单个事务的数据库。如果可能,请考虑将该过程用于步骤6。如何实现这一目标将是一个单独的问题。