我有一个关于如何处理存储复杂工作流状态以便在数据库中处理任务的最佳实践的问题.我一直在网上看无济于事,所以我想我会问社区他们认为最好的.
这个问题出自我在先前问题中给出的相同"BoxItem"示例.在我的系统中跟踪这个"BoxItem",因为它上面执行了各种任务.任务可能会持续几天并且与人工交互,因此BoxItem的状态必须保持不变.谁完成了任务(如果适用),并且还必须跟踪任务完成的时间.
首先,我通过在"BoxItems"表中为每个需要完成的人工交互任务添加三个字段来解决这个问题:
TaskName是否完整
日期任务名称完成
用户任务名称完成
这在工作流程很简单时起作用......但现在它已经发展成一个复杂的过程(流程中> 10个可能的人类交互...其中大约一半是可选的,可能或可能不会为BoxItem完成,这导致我开始添加"Do TaskName "字段以及那些可选任务),我发现应该是一个简单的表现在有40个左右的字段专门用于保留这个状态信息.
我发现自己在问是否有更好的方法来做到这一点......但我不知所措.
我的第一个想法是制作一个通用的"BoxItemTasks"表,它定义了可以在给定的盒子上完成的任务,但我仍然需要单独保存日期和用户信息,所以它没有真正帮助.
我的第二个想法是,也许这无关紧要,我不应该担心这张桌子有40个或更多的字段用于保留国家......而且我可能只是偏执狂.但感觉这就是要保留的大量信息.
无论如何,我不知道第三种选择可能是什么,或者上述两种选择中的一种是否合理.我可以看到这个工作流程在将来可能变得更加复杂,而且对于每个新任务,我需要添加3-4个字段以支持跟踪它...感觉它正在失控.
在这个情况下,你会怎么做?
我应该注意到这是现有系统的维护,一个没有ORM的系统,所以我不能把它留给ORM来处理它.
编辑:
凯夫,你在谈论做这样的事情:
(PK)BoxItemID
(其他不相关的东西)
(PK)BoxItemID
(PK)BoxItemTaskID
完成了
DateCompleted
UserCompleted
(PK)TaskType
描述(如果有必要的话)
嗯...那会起作用......它代表需要改变我目前处理SQL查询的方式,看看哪些项目处于什么状态,但从长远来看,这样的事情看起来会更好(没有做一个基本的设计改变,比如序列化的想法代表......虽然如果我有时间,我想按照我的想法这样做.).
这就是你提到Kin的原因,还是我对它的关注?
编辑:啊,我看到你的想法与"最后的行动",以确定当前的状态...我喜欢它!我认为这可能对我有用......我可能需要稍微改变它(因为在某些时候任务同时发生),但这个想法似乎是一个好主意!
EDIT FINAL:所以总结一下,如果其他人在将来用同样的问题来看这个......如果你的系统将信息预先加载到某个可查询的界面中,那么序列化方法会很有用(即不是直接调用数据库本身,就像我正在研究的ad-hoc系统那样,但是如果你没有这个,那么附加表的想法似乎应该运行良好!谢谢大家的回复!
我想将以下mod_rewrite规则转换为Nginx等价物:
RewriteRule ^foo/(.*)$ /bar/index.php?title=$1 [PT,L,QSA]
RewriteRule ^foo/*$ /bar/index.php [L,QSA]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我有:
rewrite ^foo/(.*)$ /bar/index.php?title=$1&$query_string last;
rewrite ^foo/?$ /bar/index.php?$query_string break;
Run Code Online (Sandbox Code Playgroud)
问题是(我认为!)查询字符串没有被追加.我还没有找到将QSA参数移植到Nginx的方法.
我正在阅读有关自我参照has_many:通过今天的数据情况,因为我正在尝试构建一个使用它们的Rails应用程序.我在互联网上发现了这个例子,我对此有疑问.让我在这个人的博客上发布这个示例代码:
create_table :animals do |t|
t.string :species
end
create_table :hunts do |t|
t.integer :predator_id
t.integer :prey_id
t.integer :capture_percent
end
class Animal < ActiveRecord::Base
has_many :pursuits, :foreign_key => 'predator_id',
:class_name => 'Hunt',
:dependent => :destroy
has_many :preys, :through => :pursuits
has_many :escapes, :foreign_key => 'prey_id',
:class_name => 'Hunt',
:dependent => :destroy
has_many :predators, :through => :escapes
end
class Hunt < ActiveRecord::Base
belongs_to :predator, :class_name => "Animal"
belongs_to :prey, :class_name => "Animal"
end
Run Code Online (Sandbox Code Playgroud)
假设我正在构建一个列出其数据库中第一个动物的网页.此标题下方是百分比列表(capture_percent).每个百分比指的是这个页面的动物狩猎的动物,但它不会告诉你动物的名字,只是百分比.单击任何给定的百分比将转到相应的动物页面.
我知道,这是一个难以解决的问题,但我正在努力解决这个问题.我是否必须为CapturePercent创建一个单独的表?
我有这个测验应用程序,我匹配人们输入的正确答案.就目前而言,我所做的基本上是:
if ($input =~ /$answer/i) {
print "you won";
}
Run Code Online (Sandbox Code Playgroud)
这很好,好像答案是"鱼",用户可以输入"一条鱼"并被认为是一个很好的答案.
我面临的问题是,我的用户因为我是法国人,我希望能够接受用户输入"taton",答案是"tâton".
那么,我能做的是:
use POSIX qw(locale_h);
use locale;
setlocale(LC_TYPE, "fr_FR.ISO8859-15");
setlocale(LC_COLLATE, "fr_FR.ISO8859-15");
Run Code Online (Sandbox Code Playgroud)
在我的检查程序中,做一个:
$input = lc($input);
$input =~ tr/àáâãäåçèéêëìíîïñòóôõöùúûüýÿ/aaaaaaceeeeiiiinooooouuuuyy/;
Run Code Online (Sandbox Code Playgroud)
还有同样的答案.
我不喜欢它,因为我必须硬编码,而当我决定我将离开ISO-8859-15世界的UTF-8世界时,我注定要失败.
所以,我正在寻找一种方式来比较字符串,这将使"tâton" eq "taton","maçon" eq "macon"或者"macon" =~ /maçon/是真实的.
我正在研究一个传统的小型企业自动化系统(库存,销售,采购等),它有一个由SQL Server 2005托管的单个数据库和一堆客户端应用程序.主客户端(由所有用户使用)是MS Access 2003应用程序(ADP),其他客户端包括各种VB/VBA应用程序,如Excel加载项和命令行实用程序.
除了60个左右的表(大多数是3NF)之外,数据库还包含大约200个视图,大约170个UDF(主要是标量和表值内联的),以及大约50个存储过程.正如您可能已经猜到的那样,所谓的"业务逻辑"的某些部分被封装在大量的T-SQL代码中(因此被所有客户端共享).
总的来说,系统的代码(包括T-SQL代码)组织得不是很好,可以说是非常重构的.特别是,大多数表的模式都适用于所有类型的重构,小型(如列重命名)和大型(如规范化).
FWIW,我有很长很好的应用程序开发经验(C/C++,Java,VB和诸如此类的东西),但我不是DBA.所以,如果这个问题看起来很愚蠢,现在你知道为什么会这样.:-)
在考虑重构所有这些混乱时(当然是以和平方式),我想出了以下想法:
对于每个表,创建一个"包装器"视图,其中(a)具有该表具有的所有列; (b)在某些情况下,根据表的"实际"列有一些额外的计算列.
这种附加计算列的典型(尽管是简单的)示例是从产品的常规价格和折扣得到的产品的销售价格.
重新组织所有代码(T-SQL和VB/VBA客户端代码),以便只有"包装器"视图直接引用表.
因此,例如,即使应用程序或存储过程需要从表中插入/更新/删除记录,它们也会针对相应的"表包装器"视图执行此操作,而不是直接针对表.
因此,基本上这是关于通过视图将所有表与系统的其余部分隔离开来.
这种方法似乎提供了很多好处,特别是从可维护性的角度来看.例如:
当要重命名表列时,可以在不重写所有受影响的客户端代码的情况下完成.
实现派生属性更容易(比使用计算列更容易).
您可以有效地为列名称添加别名.
显然,所有这些好处都必须有一些代价,但我不确定我是否看到了潜伏在那里的所有渔获物.
有人在实践中尝试过这种方法吗?有哪些主要缺陷?
一个明显的缺点是维护"包装"视图与其相应表同步的成本(表中的新列也必须添加到视图中;从表中删除的列也必须从视图中删除;等等).但是这个价格似乎很小,而且可以使整个代码库更具弹性.
有没有人知道任何其他更强的缺点?
例如,使用所有这些"包装"视图而不是表格很可能会对性能产生一些不利影响,但这种影响是否足以让人担心呢?此外,在使用ADODB时,即使只基于少数连接表,也很容易获得不可更新的记录集.那么,"包装"观点是否会使事情变得更糟?等等等等...
任何评论(特别是共享的实际经验)将不胜感激.
谢谢!
PS我接下来讨论了"包装"视图的想法:
该文章建议避免上述方法.但是......我在文章中没有看到任何反对这个想法的充分理由.恰恰相反,在其创建视图的充分理由列表中,几乎每个项目都是为什么为每个表创建"包装"视图(特别是在遗留系统中,作为重构过程的一部分)如此诱人的原因).
这篇文章真的很古老(1999),所以无论什么理由都好,那么现在可能已经不再好了(反之亦然).使用最新版本的SQL Server和MS Access,听到最近考虑过甚至尝试过这个想法的人真的很有意思......
我是一封电子邮件n00b,但我正在开发一个发送带有Unicode字符的HTML电子邮件的应用程序(正如我的朋友所说"享受编码地狱").
的Subject:报头来自用户的输入,并且因此可以包含Unicode字符.一些邮件客户端(如GMail和Outlook 2007)可以正常使用,但从我的阅读中看来,正确的方法是对标题使用MIME编码字编码.
我找不到一个Ruby库来做这件事.有吗?
此外,是否有一个标题要添加,告诉邮件客户端在显示邮件时使用UTF-8?我们发送多部分电子邮件,所以我们Content-Type是multipart/mixed.Apple Mail.app特别没有使用正确的编码,即使它在各个部分中指定为UTF-8.
我试图将图像文件发布到服务器.最初我在家里没有代理测试我的脚本,它工作正常.但是当我在学院使用相同的脚本时,它会抛出一些错误.上传图像的功能如下
function upload($filepath,$dir)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_PROXY, 'localhost:7777');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'ae07b026:kpack');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_URL, 'http://finalytics.in/sites/scrap/uploader.php' );
$post_array = array(
"my_file"=>"@".$filepath,
"upload"=>"Upload",
"dir"=>$dir
);
print_r($post_array);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_array);
$response = curl_exec($ch);
echo $response;
}
Run Code Online (Sandbox Code Playgroud)
和uploader.php是一个只保存图像的普通文件.
我得到的错误是这样的
ERROR
The requested URL could not be retrieved
While trying to process the request:
POST /sites/scrap/uploader.php HTTP/1.1
Proxy-Authorization: Basic YWUwN2IwMjY6a3BhY2s=
User-Agent: Mozilla/4.0 (compatible;)
Host: finalytics.in
Accept: */*
Proxy-Connection: …Run Code Online (Sandbox Code Playgroud) 我有一个带有可能的命令行参数的字符串(使用Read-Eval-Print-Loop程序),我希望它在传递给Getopt :: Long时被解析为类似于命令行参数.
详细说明:
我有一个字符串
$str = '--infile /tmp/infile_location --outfile /tmp/outfile'
Run Code Online (Sandbox Code Playgroud)
我希望它被GetOptions解析,以便我更容易添加新选项.
我能想到的一个解决方法是将字符串拆分为空格,并用新数组替换@ARGV,然后调用GetOptions.就像是 ...
my @arg_arr = split (/\s/, $input_line);
# This is done so that GetOptions reads these new arguments
@ARGV = @arg_arr;
print "ARGV is : @ARGV\n";
GetOptions (
'infile=s' => \$infile,
'outfile=s' => \$outfile
);
Run Code Online (Sandbox Code Playgroud)
有没有好/更好的方法?
我需要使用LINQ to SQL将记录插入到没有主键的表中.桌子设计很差; 我无法控制表格结构.该表由几个varchar字段,文本字段和时间戳组成.它用作其他实体的审计跟踪.
完成插入的最佳方法是什么?我可以扩展此表的Linq分部类并添加"假"密钥吗?我对任何黑客都持开放态度,无论如何.
我正在开发一个网络应用程序(它在Visual Studio 2008中的asp.net mvc框架测试版中),并希望版本控制它.如何对App_Data文件夹中的数据库文件(*.mdf,binary)进行版本控制.
有没有办法只存储表和数据库的任何定义,或者我真的需要版本控制它的内容?
database ×2
perl ×2
refactoring ×2
ruby ×2
activerecord ×1
associations ×1
comparison ×1
curl ×1
diacritics ×1
email ×1
getopt-long ×1
linq ×1
linq-to-sql ×1
mod-rewrite ×1
nginx ×1
php ×1
post ×1
proxy ×1
regex ×1
sql ×1
sql-server ×1
string ×1
unicode ×1
utf-8 ×1
workflow ×1