【问题标题】:Writing procedures for multi-tenant database, schema as variable多租户数据库编写程序,模式为变量
【发布时间】:2012-07-06 02:09:55
【问题描述】:

我正在设计一个多租户数据库。许多基于每个租户所需的操作已被编写为存储过程。几乎所有这些都使用动态 SQL 执行,因为除了动态语句之外,我还没有找到区分模式的方法。

EXEC( 'SELECT * FROM ' + @SchemaName + '.Contacts' )

有什么方法可以创建一个表示架构的变量,这样我就可以调用 select 语句而不用动态构建它们?

SELECT * FROM @TheSchema.Contacts

SQL Server 2008

【问题讨论】:

  • @TheSchema 在这里真正代表什么?自定义架构,还是数据库名称和架构名称?
  • 只是架构。数据库隐含在连接中。

标签: sql sql-server-2008 schema prepared-statement multi-tenant


【解决方案1】:

FWIW 我发现按数据库区分客户比按模式区分客户更有用。原因?

  1. 所有模式都可以具有相同的过程,因此从模型中派生它们,而不必创建任何东西。部署到多个数据库并不比部署到多个架构复杂,实际上我认为更复杂,唯一的区别是应用程序必须知道要引用哪个数据库而不是哪个架构。

  2. 不同的客户可以有不同的恢复模式,按不同的计划进行备份等。这可以改进您的备份/恢复计划,尤其是在数据集变大时。

  3. 将每个客户都放在一个单独的数据库中,如果租户对当前服务器来说太大,则可以很容易地将其移动到不同的服务器。仅为其架构提取数据和对象将非常复杂。

  4. 某些客户可能在法律和/或合同上要求您不要将他们的数据存储在与其他客户相同的数据库中。

【讨论】:

  • 虽然我很感谢您的反馈,但我们已经做出了选择。而不是我。我只是想找到一种方法使程序更易于使用。
  • 好吧,您不能将变量用于数据库、模式、表和列等顶级实体,因此在动态 SQL 之外(或通过使用 PowerShell、C# 等替换令牌从外部生成脚本)。 ) 我不知道有没有办法做到这一点......
  • 谢谢,这正是我想知道的。
【解决方案2】:

一个更简单的解决方案是将存储过程保存在每个租户数据库中并在其中执行它。

【讨论】:

  • 如果我正在编写一个存储过程来实际在其中创建模式和表,我无法做到这一点。对这种情况有什么建议吗?
  • @Sparafusile 为什么元数据创建过程使用动态 SQL 会是一件坏事?
  • @Sprafusile,通常您使用数据库脚本文件创建租户数据库。不是通过存储过程。
  • @Aaron Bertrand 我并不是说它有什么问题,只是想知道是否有替代方案。 srini.venigalla 它是多租户模式,而不是数据库。
【解决方案3】:

这个问题有点老了,但我正在考虑将此选项作为一种节省成本的措施 - 因为许多云提供商对每个数据库收费并且与存储相关的成本较低 - 特别适用于多租户小型数据库。

据我了解,可以为登录设置默认架构,因此,为每个登录设置一个架构会自动将该架构用于所有查询和存储过程。遇到这个问题的人需要考虑的事情。

【讨论】:

  • 这是一个很好的观点,我知道这一点。我的问题更适合维护脚本,例如,您可能需要遍历模式列表并将列添加到特定表。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 2014-11-01
相关资源
最近更新 更多