【问题标题】:How to set up multiple Oracle databases (schemas) with the same user?如何使用同一用户设置多个 Oracle 数据库(模式)?
【发布时间】:2012-04-05 01:02:27
【问题描述】:

我们公司继承了一些在 C# Visual Studio 2010、Windows 7 和 Oracle 11g 上运行的软件。经过一番努力,我们让软件运行起来,并建立了一个稳定的数据库(模式)。

我们现在开始将一些数据从旧系统迁移到这个“新”系统。但是,我不想弄乱我们的工作模式,因为我预计我们的数据导入需要进行一些反复试验。

我想做以下事情: 假设我们现有的模式称为 PROD。我想创建一个名为 TEST 的第二个模式,我们可以将其用于导入的数据。然后,在 C# 代码中,我可以在两个数据库模式之间切换时切换数据源的名称。问题是此连接的用户名和密码出现在代码中分散的许多地方。为了避免每次在“数据库环境”之间切换时都必须在多个位置更改用户凭据,我想创建一个用户来访问 PROD 和 TEST。

但是,how to grant user privilege on specific schema? 表示这是不可能的。 Correct way to give users access to additional schemas in Oracle 建议了一种在对象级别授予访问权限的方法,但这还不够:我基本上希望一个用户可以访问两个相同的模式(PROD 和 TEST)。完成此操作后,我想开始修改 TEST 以开始我们的数据导入。

我也尝试在不同的端口上将 TEST 创建为单独的 Oracle 数据库安装,但是当尝试在这个新实例上创建我的用户时,我仍然遇到用户已经存在的冲突(因为它是在原始数据库安装)。

我的用户已经存在并且可以访问 PROD。我如何让他也可以访问 TEST?或者如何解决更普遍的问题,即在使用 Oracle 的应用程序中定义 PROD 和 TEST 数据库?

在 MySQL 中这将是微不足道的,但我不知道如何在 Oracle 中执行此操作。我对 Oracle 很陌生。

【问题讨论】:

  • one single user to have access to two identical schemas 是什么意思?在 oracle db 中,用户与模式几乎相同。哪个用户has access to PROD 是什么意思?
  • 澄清:在代码中,我们定义了用于连接到 oracle 数据库的用户名和密码。此用户名和密码在不同位置的代码中进行了硬编码。此用户名/密码用于连接到模式,例如 A(正确地,仅在一个地方定义)。现在我想创建第二个模式,比如 B,在其上对数据导入进行一些测试。 B 必须使用与 A 相同的用户名/密码,因此我不必在整个应用程序中更改这些详细信息。然后我可以通过在一个地方更改架构名称来简单地在应用程序中的 A 和 B 之间切换。
  • 在 oracle DB schema=db 用户中。您可以在asktom.oracle.com/pls/asktom/… 阅读语义上的差异。现在,你说connect to schema A 是什么意思?你的意思是你从你的应用程序中以用户 A 的身份连接到数据库吗?还是对架构 A 中的对象(= 用户 A 拥有的对象)具有权限的不同数据库用户?
  • 感谢 asktom 链接 - 它解释了我遇到困难的原因。我希望同一个用户可以访问(或成为所有者)两个不同的数据库(模式)。在 MySQL 中,我会简单地创建一个具有两个数据库的用户,并赋予两个数据库的用户权限。然后我会按名称引用正确的数据库。

标签: c# windows visual-studio-2010 oracle11g


【解决方案1】:

授予权限的问题有already been answered

现在,作为一个整体来回答您的问题:我是否正确地阅读了您想要更新数据库架构,但您想要将其与另一个架构保存在同一个数据库中,并在看似生产数据库的情况下运行两者?如果是这样,请再读一遍,让它深陷其中的危险性。

当从一个“架构”迁移到另一个“架构”时,作为软件更新,创建新数据库并迁移数据会更安全。这为您提供了很多机会,因为您可以在调整脚本时炸毁新数据库。

如果您希望软件中的摩擦尽可能小,您需要做几件事:

  1. 从决定在多个地方硬编码连接信息的白痴那里重构代码。您需要将字符串放在一个位置,并确保将数据访问层 (DAL) 代码提取到其自己的类中。
  2. 考虑创建不依赖于数据库模式的域对象。我认为这是强制性的,但是您可以不这样做就逃脱。我仍然会创建域对象,即使它们与 PROD 架构表匹配,因为如果您从一个架构移动到另一个架构,则不应使用数据构造。
  3. 为您的数据访问层 (DAL) 创建接口
  4. 使用接口将当前数据架构通过当前 DAL 映射到域对象。
  5. 使用接口将新架构通过新 DAL 映射到域对象。
  6. 创建工厂(或使用提供者模式)以确定您将使用哪个 DAL 对象(这使得应用程序可配置为旧的或新的“模式”

【讨论】:

  • 系统尚未投入生产。 PROD 和 TEST 只是两个不同数据库(模式)名称的示例。这听起来像是最终的最终解决方案。但是,代码重构目前不是我们的任务。我们只需要对数据做一些工作作为开始。所以我只是希望能够在需要时使用相同的用户名/密码连接到 PROD 数据库,并在需要时连接到 TEST 数据库。而且我需要在两者之间轻松切换。
【解决方案2】:

我假设您有一个架构 PROD 和一个 DBUSER,它们对此架构中的对象拥有一些特权。
DBUSER 的名称和密码在整个应用程序中都是硬编码的。
您已经创建了一个新架构 TEST,它看起来与 PROD 相同(包括对 DBUSER 的授权)。
无论应用程序执行什么操作,您都希望它:

UPDATE some_table set ...

它将更新TEST 中的some_table 表,而不是PROD
我的建议是使用和更改SYNONYMS,即-
当您想在PROD 中更新some_table 时,请执行以下操作:

CREATE OR REPLACE PUBLIC SYNONYM some_table for prod.some_table;

当您想在TEST 中更新some_table 时,请执行以下操作:

CREATE OR REPLACE PUBLIC SYNONYM some_table for test.some_table;

【讨论】:

  • 同义词是否意味着我不必更改调用 (c#) 代码?因此,如果 some_table 的同义词是 PROD.some_table,“UPDATE some_table”将更新 PROD,如果在特定时间同义词是 TEST.some_table,则将更新 TEST? (提供的链接表明,如果同义词名称与模式对象相同,则对象名称必须以模式名称开头) 1)所以要切换:使用 TEST 我为 TEST 设置同义词并再次使用 PROD 我删除 TEST 的同义词并为 PROD 创建同义词? 2) 如何为所有模式对象创建同义词,以便 my_object 指向所有对象的 schema.my_object?
  • 假设您有 3 个模式 A、B 和 C。A 和 B 都有一个表名 T1。在 A 和 B 中,T1 都被授予对 C 的选择。如果您将数据库连接到模式 C(作为用户 C)并且您想选择表单 T1,您应该说 T1 的哪个模式,语法为 A.T1B.T1 (取决于你想要哪个 T1)。如果 C 有一个同义词,比如 A.T1 的“TT1”,或者如果 A.T1 有一个公共的同义词“TT1”,那么 C 可以从 TT1 中选择,它实际上是 A.T1。如果您将 TT1 更改为 B.T1 的同义词,则从 TT1 中选择将给出 B 的 T1 的结果。
  • 好的。但这意味着我必须在代码中的任何地方更改 SQL 命令,因为 A 和 B 将具有相同的表名,并且在 SQL 代码中引用了表名(没有任何前缀)。示例:A 和 B 都将包含表 T1,并且 C# 代码包含诸如“select * from T1”之类的语句。我不能将 T1 用作同义词(没有前缀),并且为从代码中引用的每个表或视图添加前缀或更改 T1 的名称是一种侵入性练习。更改代码尚不在我们的范围内。所以我不认为同义词会起作用。
  • 您可以为“A.T1”使用公共同义词“T1”(我在示例中使用“TT1”只是为了更清楚)。顺便说一句,你为什么要搞砸这一切?为什么不只拥有两个具有完全相同架构的数据库实例,然后在您的 c# 代码中更改连接字符串?
  • 连接在 C# 代码中的多个位置定义 - 正如 Gregory 建议的那样,代码实际上需要一些重构。在连接池、odbc 等方面也使用不同的连接方法。我们还没有强制要求进行任何真正的代码更改。首先需要启动数据库。
【解决方案3】:

在 C# 代码中未正确处理与 Oracle 的连接,这就是造成困难的原因。

如果数据访问层按照 Gregory 的建议单独定义,或者如果 A.B 的回答指出在 SQL 语句中使用更通用的命名约定,那么在两个数据库之间切换会简单得多。

由于我们的任务目前不涉及对代码进行任何更改/重构,我正在使用备份和恢复方法:

我创建了工作数据库的备份。然后我对数据库进行必要的测试和更改。如果我需要恢复到工作数据库,我会再次创建“测试”数据库的备份并恢复原始工作数据库,在恢复的情况下使用适当的标志替换现有表。这使我能够在“工作”数据库和“测试”数据库之间来回切换。

这并不理想,因为它确实需要一些时间来执行备份和恢复,但可以在不影响 C# 代码的情况下工作,并且能够在“测试”数据库上进行工作而不影响正在工作的数据库。由于这是“测试”数据库开始工作之前的临时场景,因此这是我将遵循的方法。

正如其他答案所指出的那样 - 修复/重构/概括连接代码需要更通用 - 我相信这是最好的方法,我不立即这样做的唯一原因是因为我们还没有强制更改代码。

【讨论】:

    猜你喜欢
    • 2019-11-21
    • 2013-01-22
    • 2017-05-27
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2018-07-16
    相关资源
    最近更新 更多