让我们假设您正在为零售连锁店撰写应用程序。因此,您可以设计对象模型,以便将“Store”定义为核心业务对象和许多支持对象。假设'Store'如下所示:
class Store implements Validatable{
int storeNo;
int storeName;
... etc....
}
因此,您的客户告诉您必须将Excel商店日程表从Excel工具箱导入到应用程序中,您必须在其上运行一系列验证。例如,'StoreIsInSameCountry';'StoreIsValid'等等。因此,您将设计一个规则界面来检查所有业务条件。像这样:
interface Rule T extends Validatable> {
public Error check(T value) throws Exception;
}
现在,问题来了。我正在从这个excel表上传2000个商店。因此,我最终会多次运行为商店定义的每个规则。如果我对数据库有4个规则= 8000个查询,即连接池有16000个命中。对于我只需要检查商店是否存在的简单检查,查询将是:
SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID = ?
这样我就可以获得我的'Store'对象。当我从数据库中没有得到任何东西时,那个商店就不存在了。因此,对于这样一个简单的检查,我将不得不为2000个商店点击数据库2000次。
或者,我可以这样做:
SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID in (1,2,3..... )
这个查询实际上返回的速度要快于2000次以上的查询。 但是,对于只能为单个商店运行规则的设计,它并不顺利。
我知道使用IN不是建议的方法。那么,你认为我应该怎么做?我应该继续在这里使用IN,因为它在这种情况下会提供更好的性能吗?或者我应该改变我的设计?
如果你穿着我会做什么,最佳做法是什么?
答案 0 :(得分:2)
这样我就可以从数据库中获取我的'Store'对象。当我从数据库中没有得到任何东西时,那个商店就不存在了。因此,对于这样一个简单的检查,我必须为2000个商店点击数据库2000次。
这是不应该做的事情。
创建一个临时表,在表格中填入您的值和JOIN
此表格,如下所示:
SELECT STORE_ATTRIB1, STORE_ATTRIB2...
FROM temptable tt
JOIN STORE s
ON s.STORE_ID = t.id
或者这个:
SELECT STORE_ATTRIB1, STORE_ATTRIB2...
FROM STORE s
WHERE s.STORE_ID IN
(
SELECT id
FROM temptable tt
)
我知道使用IN不是建议的方法。那么,你认为我应该怎么做?我应该继续在这里使用IN,因为它在这种情况下会提供更好的性能吗?或者我应该改变我的设计?
IN
过滤器重复出来。
如果您希望为列表中的每个重复值选择每个符合条件的行,请使用JOIN
。
IN
绝不是“不建议的方法论”。
事实上,曾经有一段时间某些数据库没有高效地支持IN
查询,这就是为什么民间智慧仍然建议不要使用它。
但是如果您的store_id
被正确编入索引(并且很可能是,如果它看起来是PRIMARY KEY
),那么主要数据库的所有现代版本(即Oracle
,SQL Server
,MySQL
和PostgreSQL
)将使用有效的计划来执行此查询。
请参阅我的博客中的这篇文章,了解SQL Server
中的效果详情:
请注意,在设计合理的数据库中,验证规则也是基于集合的。
予。即您将验证规则实施为针对temptable
的查询。
但是,要支持旧规则,您可以从temptable row-by-agonizing-row中选择值,应用规则并删除未通过验证的值。
答案 1 :(得分:1)
SELECT store_id FROM store WHERE store_active = 1
甚至
SELECT store_id FROM store
会告诉您单个查询中的所有活动商店。您现在可以对您知道存在的商店进行其他测试,并且您已经为数据库节省了1,999次点击。
如果您有相对无争议的数据库访问权限,并且没有时间限制整个事情要花多长时间,那么您就不必担心一遍又一遍地访问连接池。毕竟,这就是它的设计目标!
答案 2 :(得分:0)
我认为这更像是一个商业问题,其中包含客户运行导入的频率参数,实施任一解决方案所需的时间,以及每小时的时间费用。
如果它偶尔运行一次,我认为可以接受一些不好的性能,特别是如果你能用干净的代码快速完成工作。
答案 3 :(得分:0)
...规则只能在单个商店中运行。
管理业务规则和性能是一项艰巨的任务,因此有一个库("Persistence Layer")可以做到这一点。您定义规则,然后执行大量命令,然后在一次查询中(通过使用临时表而不是'IN')从数据库中提取库,无论规则需要什么,然后将其传递给规则。 here中有一个验证程序的示例。