我可以干运行/ sandbox sql命令吗?

eug*_*ill 6 sql database sqlite postgresql ruby-on-rails

我正在尝试构建一个小型rails应用程序,以游戏格式向初学者教授sql.它的一部分是一个命令行,其中的用途试图解决sql的问题.在后端我想对测试数据库运行他们的sql命令,并检查结果以查看他们的命令是否正确.

我目前的想法是为课程的每个阶段创建sqlite数据库,然后在每个用户到达该阶段时为该数据库创建该数据库的副本.

我认为这会奏效,但我担心效率.

我的问题是,是否有一种有效的方法让用户运行SQL命令(包括drop,alter等),得到结果,但实际上并没有对db本身进行任何更改,实质上是任意sql命令的干运行.我熟悉sqlite和postgres,但我对其他数据库开放.

Erw*_*ter 11

在Postgres里,你可以做多少交易回滚底:

BEGIN;

UPDATE foo ...:
INSERT bar ...;
SELECT baz FROM ...;
CREATE TABLE abc...;   -- even works for DDL statements
DROP   TABLE def...;
ALTER  TABLE ghi ...:

ROLLBACK;   -- !
Run Code Online (Sandbox Code Playgroud)

手册中的更多内容: BEGIN ROLLBACK

但请注意,有些事情无法回滚.例如,序列不会回滚.或者像dblink调用这样的特殊命令.

并且某些命令无法在与其他人的交易中运行.喜欢CREATE DATABASEVACUUM.

此外,并发加载可能会产生副作用,例如死锁.但不太可能.您可以根据需要设置事务隔离级别,以排除任何副作用(以性能为代价).

我不会用合理的数据来做这件事.意外事故的风险太大了.让用户执行任意代码是一种难以控制的风险.但对于训练环境来说,这应该足够好了.

模板数据库备份它.如果出现问题,这是恢复基本状态的最快方法.示例(查看上一章):
截断Postgres数据库中的所有表

这也可以用作强力替代方案:为每个受训者提供原始的新数据库.


Cra*_*ger 5

虽然您可以在事务中运行他们的代码,然后尝试在回滚之前检查同一事务中的结果,但这会遇到一些挑战。

首先,如果他们的代码中有任何错误,交易就会中止。除了“失败,这是错误消息”之外,您无法说出任何其他信息。特别是,您将无法检查错误发生之前的部分结果。

其次,如果您在单个数据库中进行并行运行,锁定会困扰您。每个会话都会获得锁,通常是元组或整个关系上的排他锁。其他会话将阻塞等待该锁。这意味着您必须连续进行测试运行。在您的环境中这可能不是问题,但值得考虑。

第三,正如 Erwin 指出的那样,您必须使检查代码对序列值等内容不敏感,因为它们不会在回滚时重置。

出于所有这些原因,我强烈建议:

CREATE DATABASE course_username_lesson TEMPLATE course_lesson OWNER username;
Run Code Online (Sandbox Code Playgroud)

...或者省略模板数据库的使用,只让您的 Rails 应用程序使用每个用户的迁移来设置一个空白数据库。这可能更简单,因为这意味着您不必维护模板数据库。

PostgreSQL 服务器对数百个数据库非常满​​意,至少在预计不会在峰值生产负载下执行时是这样。

您可能想查看http://sqlfiddle.com/和许多其他现有的基于 Web 的 SQL 编辑器/培训工具,其中许多都是开源的。