情境:
我有一个应用程序(C#),它需要一个由用户设置的SQL数据库和登录。连接后,它会检查是否存在多个表,如果找不到则会创建它们。
如果我发布依赖于新列的程序的新版本,我希望通过让程序能够向这些表添加列来扩展它。
问题:
以编程方式检查现有SQL表的结构并创建或更新它以匹配预期结构的最佳方法是什么?
我计划迭代所需列的列表,并在不包含新列时更改现有表。我不禁想知道是否存在不同或更好的方法。
标准
以下是我的一些期望和自我规则:
示例:
这是一个示例表(因为可视化示例有帮助!):
id datetime sensor_name sensor_status x1 x2 x3 x4 1 20100513T151907 na019 OK 0.01 0.21 1.41 1.22 2 20100513T152907 na019 OK 0.02 0.23 1.45 1.52
然后,在新版本中,我可能想要添加列x5
。 “x
- 列”是接受null的所有数据存储列。
修改
我更新了上面的示例表。它更像是一个日志而不是父表。因此,传感器将在此记录表中重复显示记录的值。一个单独的父表包含关于传感器的地理和其他后勤信息,使我想要修改子表的表。
答案 0 :(得分:2)
这是一个非常麻烦的功能,您正在考虑实施。我建议反对它,而是考虑使用第三方工具编写脚本更改,例如Red Gate的Sql Compare:http://www.red-gate.com/products/SQL_Compare/index.htm
如果您有疑问,请考虑下载该软件的试用版并在两个数据库上执行结构差异脚本,但有一些非平凡的差异。您将从结果中看出,此类操作的注意事项远非简单。
围绕这类问题的另一种方法是使用EAV模型重新设计数据库:http://en.wikipedia.org/wiki/Entity-attribute-value_model(透视动态添加行,因此永远不会改变结构。它有自己的问题,但它非常灵活。)< / p>
(要使用diff工具,你必须拥有所有db版本的副本,并创建diff脚本,这些脚本会在新版本和升级版本中运行并执行。这是一个非常混乱的维护.EAV这是一种类似这样的事情。它因为不像传统的数据库结构那样具有很高的性能,但我已经多次使用它并取得了巨大的成功。事实上,我有一个符合HIPAA标准的EAV db(Sql Server 2000)已经生产了六年以上,其中几个EAV表包含数十或数百行,并且它仍然很强大,没有大的减速。当然,我们不会对该数据库进行大量报告对于报告,我们有一个导出将数据展平为关系结构。)
答案 1 :(得分:2)
我看到的常见解决方案是在您的数据库中存储某处版本信息。也许有一张非常小的桌子:
CREATE TABLE DB_PROPERTIES (key varchar(100), value varchar(100));
然后你可以添加一行:
key | value
version | 12
然后,您可以创建一个sql更新脚本(或一组脚本),将db从版本12
更新为版本13
。
declare v varchar(100)
select v=value from DB_PROPERTIES where key='version'
if v ='12'
#do upgrade from 12 to 13
elsif v='11'
#do upgrade from 11 to 13
...and so on
根据您希望支持的升级路径,您可以添加更多案例。您显然也可以将此升级逻辑移动到C#和/或任何适合您的设计中。但是,将数据库版本信息存储在数据库中将使得更容易找出已存在的内容,而不是单独查询所有数据库结构。
答案 2 :(得分:0)
如果你必须以依赖应用程序制作表更改的方式构建某些东西,那么你的设计是有缺陷的。您应该有一个传感器值的相关表(x1,x2等),然后您只需添加另一条记录而不必创建新列。
建议的子表结构
READINGS ID int Reading_type varchar(10) Reading_Value int
然后表格中的数据为:
ID Reading_type Reading_value 1 x1 2 1 x2 3 1 x3 1 2 x1 7
答案 3 :(得分:0)
尝试Microsoft.SqlServer.Management.Smo
这些是一组C#类,它们为SQL Server数据库对象提供API
Microsoft.SqlServer.Management.Smo.Table有一个Columns Collection,允许您查询和操作列。
玩得开心。