我需要一些关于如何设计数据库层的输入。
在我的应用程序中,我有一个T列表.T中的信息包含来自多个数据库表的信息。
当然有多种方法可以做到这一点。 我想到的两种方式是:
聊天数据库层和可缓存:
List<SomeX> list = new List<SomeX>();
foreach(...) {
list.Add(new SomeX() {
prop1 = dataRow["someId1"],
prop2 = GetSomeValueFromCacheOrDb(dataRow["someId2"])
});
}
我在上面看到的问题是,如果我们想要一个包含500个项目的列表,它可能会产生500个数据库请求。具有所有网络延迟和那。 另一个问题是,在我们从数据库中获取列表之后但在我们尝试从cache / db获取列表之前,用户可能已被删除,这意味着我们将遇到null问题。我们必须手动处理。 好处是它可以高度缓存。
不健谈但不可缓存:
List<SomeX> list = new List<SomeX>();
foreach(...) {
list.Add(new SomeX() {
prop1 = dataRow["someId1"],
prop2 = dataRow["someValue"]
});
}
我在上面看到的问题是它难以缓存,因为可能所有用户都有唯一的列表。另一个问题是它会有很多连接,这可能导致对数据库的大量读取。 好消息是我们确定在查询运行后存在所有信息(内连接等)
非如此健谈,但仍可缓存
第三个选项可能是首先循环遍历数据行,并收集所有必需的someId2,然后再发出一个数据库请求以获取所有SomeId2值。
答案 0 :(得分:1)
“我在上面看到的问题是,如果我们想要500个项目的列表,它可能会产生500个数据库请求。具有所有网络延迟和那个。”
真。在迭代查询时,还可能会创建不必要的争用并消耗维护锁的服务器资源。
“另一个问题是,在我们从数据库中获取列表之后但在我们尝试从cache / db获取列表之前,用户可能已被删除,这意味着我们将出现null问题。”
如果我接受这个引用,那么引用:
“好处是它可以高度缓存。”
不是真的,因为你已经缓存过时的数据。所以到目前为止取消了唯一的优势。
但是要直接回答你的问题,最有效的设计,似乎就是你所要求的,是使用数据库来获得它的好处,执行ACID合规性和各种约束,最明显的是pk和fk,但是还可以返回汇总的答案,以减少往返旅行和应用程序方面的浪费周期。
这意味着您要么将SQL放入您的应用程序代码中,该代码被Code Thought Police裁定为Infinite Bad Taste,要么转到sprocs。两个都有效。将代码放入应用程序使其更易于维护,但您永远不会被邀请参加任何更优雅的OOP派对。
答案 1 :(得分:0)
一些建议:
SQL是一种基于集合的语言,因此不要设计迭代循环的东西。即使使用存储过程,当基于集合的查询将解决问题时,仍然会偶尔看到游标。因此,总是尝试通过1个查询获取信息。现在有时这是不可能的,但在大多数情况下这将是。如果您有一个包含许多表的模式来提取一个语句所需的信息,您还可以设计视图以使查询更容易。
使用代理。假设我有一个具有50个属性的对象。首先,您向用户显示对象列表。在这种情况下,我将创建最重要属性的代理并向用户显示,可能是2或3个重要属性,如名称,ID等。这减少了最初发送的信息量。当用户实际想要编辑或更改对象时,再进行第二次查询以获取“完整”对象。只得到你需要的东西。当层之间的序列化XML时,这对于Web来说尤为重要。
提出分页策略。大多数系统工作正常,直到它们获得大量数据,然后查询停止,因为它重新生成了1000个数据行/记录。早期和经常页面。如果您正在进行Web应用程序,可能直接在数据库中进行分页将是最高效的,因为只有分层数据在层之间发送。
数据缓存取决于数据。对于高度易变的数据(一直在变化),缓存是不值得的。对于半易失性或非易失性数据,缓存可能是值得的,但如果您使用的是内置框架,则必须直接或间接管理缓存。
使用缓存的好地方就是说你有一个邮政编码表。 Certianly,那些经常不会改变,如果您的应用程序中有一个邮政编码下拉,您可以缓存这些以提高性能。这仅是一个示例,但缓存IMO取决于数据类型。