我正在让rest-api接收指令列表,该指令列表是服务器上的特定线程应在24小时内执行的工作,称之为每日时间表。在一个时间间隔内执行相同的指令:
[
{
instructionName: string
args : [
string
...
]
startHh : int
startMm : int
endHh : int
endMm : int
}
...
]
args
的内容因instructionName
而异。该计划应保留在MySql中。线程每隔x秒应向db请求当前指令并执行一些工作。
我的问题是我不确定在数据库中存储指令列表的最佳选择是什么。如我所见,我有两个选择:
使用第一种方法,我要做的就是将concat
args
转换为单个字符串,然后将json直接解析为DTO对象并保留它,我必须注意不要存储指令名和args,以便工作线程以后可以使用不解释。工作线程可以轻松查询指令表并获取有关时间间隔的当前指令。在第二种方法中,我必须首先使用指令名找出表,看看args是否对该表有效,然后将其插入。辅助线程无法以简单的方式获取当前指令,因为指令被分隔在不同的表中。当工作线程找出要查询该线程的表时,可以确保将args正确格式化,因为它们被分为几列。
在我的应用程序中,将会有很多类型的指令,并且在应用程序的生命周期中会不断添加新的指令类型。
似乎这两种方法都存在很大的问题,我无法为我的特定用例找到最佳的方法。我想知道我是否甚至应该为这些类型的数据使用关系数据库。
任何输入表示赞赏。
最佳答案
在我的应用程序中,将有许多类型的指令和
在生命周期中将不断添加新的指令类型
的应用程序。
选择哪种解决方案取决于您对许多解决方案的定义,并不断地进行。数据库在查询现有数据方面非常出色。更改存储的数据和添加新数据非常好。更改数据库布局很糟糕。因此,您应尽量避免更改布局。
如果连续更改意味着一天要进行几次,我不建议为每个应用程序创建一张表。
即使这样,如果许多应用程序意味着1000个应用程序/参数配置,那么每个应用程序的表将导致1000个表,这是非常不希望的。
另一方面,如果您选择第一种方法,则正如您所说的,您将必须妥善保存命令及其参数。
如果您有某种可以解决问题的用例的存储库模式,则可以让存储库在将参数存储到数据库之前检查这些参数。
void ScheduleBackupTask(TimeSpan startTime, TimeSpan stopTime, ... <backup parameters>)
{
// check the parameter list, to see if they match the parameters of a backup task
// and create the command
var command = CreateBackupCommand(<backup parameters>);
ScheduleCommand(startTime, stopTime, command);
}
void ScheduleCleaningTask(TimeSpan startTime, TimeSpan stopTime, <cleaning parameters>)
{
// check the parameter list, to see if they match the parameters of a clean task
// and create the command
var command = CreateCleanCommand(<cleaning parameters>);
ScheduleCommand(startTime, stopTime, command);
}
void ScheduleCommand(TimeSpan startTime, TimeSpan stopTime, Command command)
{
using (var dbContext = new MyDbContext()
{
Schedule schedule = new Schedule(startTime, stopTime, command);
dbContext.Schedules.Add(shedule);
dbContext.SaveChanges();
}
}
每次需要支持新命令或更改命令参数时,都必须创建或更改
Create...Command
函数。只有一个地方需要检查参数。即使您选择了第二个解决方案,也需要一个函数来检查您的参数并按正确的顺序排列它们。因此,您的第二个解决方案将无济于事。
执行命令
显然,使用第一种方法可以更轻松,更快捷地查询必须执行的命令。提取命令(包括
commandType
)后,很容易执行它:IEnumerable<Command> commandsToExecute = FetchCommandsToExecute(TimeSpan time);
foreach (Command command in commandsToExecute)
{
switch (command.CommandType)
{
case CommandType.Backup:
ExecuteBackup(...);
break;
case CommandType.Clean:
ExecuteClean(...);
break;
}
}
显然,当支持新命令时,您将不得不更改开关。但是,在第二种解决方案中,您还必须更改执行功能。
总结:如果您想到许多要支持的命令,请定期
更改参数或支持的命令种类,可能会建议
具有一张包含所有要支持的命令的表。让你
存储库模式在添加/更新/之前检查参数
执行中
关于mysql - 关系数据库中的数据粒度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53093842/