请原谅我的长期问题。我有一个设计的想法,我可以使用一些评论。这样做是个好主意吗?我应该注意哪些坑落?还有其他类似的实现更好吗?
我的情况如下:
我正在重写一个连接到SQL 2008(早期它是SQL 2005)服务器的Windows窗体应用程序。该应用程序是一个工程公司的“专家系统”,我们存储有关结构的结构化数据。我们控制客户端软件的所有安装,我们没有外部客户或用户,他们都是公司内部的,并且他们都被信任不对软件或数据库做任何恶意的事情。
当前的设计没有太多的表(大约10 - 20),但其中一些有数百万条属于数百种结构的记录。到目前为止,系统性能还不错,但随着我们推动设计的极限,它开始降级。
作为重写的一部分,我正在考虑将数据库拆分为一个主数据库和几个“子”数据库,其中每个数据库都描述一个结构。每个子数据库应该具有相同的设计。这应该消除我们今天看到的性能问题,因为存储在每个数据库中的数据将小于总数据量的百分之一。
我担心的是,我们现在将获得数百个必须保持最新的数据库,而不是维护一个数据库。随着公司要求的变化(你知道它是怎样),系统不断发展,而我们试图期待减少变化的数量。因此,我们需要一个系统来跟踪系统所做的所有数据库更改,以便将它们应用于子数据库。更新客户端应用程序不会成为问题,我们可以很好地控制这方面。
我正在考虑一个更改跟踪系统,我们为master数据库中的表中的所有更改存储数据库脚本。然后,我们可以为每个更改提供版本号,并且我们可以在每个子数据库中存储当前版本号。当客户端程序连接到子数据库时,我们可以根据主数据库的当前版本号检查数据库的版本号,如果有版本号大于子数据库版本号的补丁,我们运行这些并更新子数据库到最新版本。
我认为这应该很有效。在作为新版本的数据库提交之前,将首先测试和验证对系统的任何更改。然后,在用户首次打开数据库时,将对数据库应用更改。我想我们会在应用更改时以独占模式打开数据库,但只要更改不是太频繁,这应该不是问题。
那你觉得怎么样?这会有用吗?你们有没有做过类似的事情?我们应该废弃解决方案并转而使用单片系统吗?
答案 0 :(得分:2)
您是否考虑过“构建”对大型表进行分区?这可以通过在不需要更改应用程序的情况下跨文件/物理设备分割表的存储来缓解一些增长的痛苦。
添加主轴(更多驱动器)并执行几个小时的DBA工作通常比修改/调整软件更便宜。
否则,我同意@heikogerlach和这些类似的帖子:
How do I version my ms sql database
Mechanisms for tracking DB schema changes
How do you manage databases in development, test and production?
答案 1 :(得分:1)
我有类似的情况,虽然我使用MySQL。每个数据库都有一个版本表,其中包含版本(只是一个整数)以及此版本中已更改内容的简短注释。我使用脚本来更新数据库。每个数据库更改都可以在一个函数中,或者有时一个更改由多个函数进行。函数包含函数名称中的版本号。该脚本在数据库中查找最高版本号,并仅按顺序应用具有更高版本号的函数。
这样可以轻松更新数据库(只需添加新的更改功能),并允许我在必要时快速升级已恢复的数据库(只需再次运行脚本)。
即使在此之前测试更改也允许进行防御性更改。如果你在桌子上做了一些重大的改变,并且想要安全地玩它:
def change103(...):
"Create new table."
def change104(...):
"""Transfer data from old table to new table and make
complicated changes in the process.
"""
def change105(...):
"Drop old table"
def change106(...):
"Rename new table to old table"
如果在change104()中出现问题(并抛出异常),您只需从新表中删除已转换的数据,修复更改功能并再次运行脚本。
但我不认为在客户端连接时动态更改数据库是一个好主意。有时候更改可能需要一些时间。访问数据库的软件应该与数据库的模式匹配。你有办法让它们保持同步。也许你可以发布一个新的软件版本,然后你想在客户端真正开始使用这个新软件时升级数据库。但我没试过。
答案 2 :(得分:1)
最好不要创建其他数据库。乍一看,你可能认为你会获得一些性能提升,但实际上你会得到支持噩梦。记住 - 什么可以打破,迟早会打破。
在单个数据库中执行和优化查询更简单。在单个数据库中管理用户权限要容易得多。为单个数据库进行一致的备份要容易得多。
像KenG所说,如果你需要打破你的大表 - 考虑分区它们。并添加一些驱动器:)
但首先在数据库上运行SQL profiler并优化索引和查询。数百万行通常不是一个大问题(除非你的客户需要 live 总计超过一半,在这种情况下,没有分区可以帮助)。
答案 3 :(得分:1)
我知道这是一个疯狂的答案,但在这里......
我目前有一个类似的场景,我需要在使用MS SQL Server的系统的多个位置控制数据库版本。
我现在正在做的是使用Ruby on Rails ActiveRecord Migrations来控制数据库版本。是的我知道我们正在谈论Windows系统,但这对我来说很好。 (顺便说一句,我的系统是用VB和.NET编程的)
我已经在每台服务器上安装了Rails,当我需要更新数据库模式时,我将迁移文件复制到服务器并运行rake db:migrate,它将数据库更新到最新版本或将其回滚到所需版本。< / p>
作为副作用,您将以数据库独立语言(在本例中为ruby)为数据库模式提供一组迁移文件,您可以将这些文件应用于其他数据库引擎,也可以将其置于源代码管理之下。
我知道这是一个奇怪的解决方案,其中使用了完全不同的技术,但学习新方法并没有什么坏处。您可以找到其他信息here。
自从我学习Ruby on Rails以来,我已成为一名优秀的.Net程序员。我在question之前询问了这种方法。