Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据库、请求、性能、缓存_C#_Database_Performance_Caching - Fatal编程技术网

C# 数据库、请求、性能、缓存

C# 数据库、请求、性能、缓存,c#,database,performance,caching,C#,Database,Performance,Caching,我需要一些关于如何设计数据库层的输入 在我的应用程序中,我有一个T列表。T中的信息包含来自多个数据库表的信息 当然,有多种方法可以做到这一点。 我想到的两个方法是: 聊天数据库层和可缓存: List<SomeX> list = new List<SomeX>(); foreach(...) { list.Add(new SomeX() { prop1 = dataRow["someId1"], prop2 = GetSomeValu

我需要一些关于如何设计数据库层的输入

在我的应用程序中,我有一个T列表。T中的信息包含来自多个数据库表的信息

当然,有多种方法可以做到这一点。 我想到的两个方法是:

聊天数据库层和可缓存:

List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = GetSomeValueFromCacheOrDb(dataRow["someId2"])
    });
}
List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = dataRow["someValue"]
    });
}
List List=新列表();
foreach(…){
list.Add(新的SomeX(){
prop1=dataRow[“someId1”],
prop2=GetSomeValueFromCacheOrDb(数据行[“someId2”])
});
}

我在上面看到的问题是,如果我们想要一个包含500项的列表,它可能会发出500个数据库请求。所有的网络延迟等等。 另一个问题是,在我们从数据库获取列表之后,但在我们试图从缓存/db获取列表之前,用户可能已经被删除,这意味着我们将遇到空问题。我们必须手动处理。 好的一面是它具有高度的可缓存性

不健谈但不可缓存:

List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = GetSomeValueFromCacheOrDb(dataRow["someId2"])
    });
}
List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = dataRow["someValue"]
    });
}
List List=新列表();
foreach(…){
list.Add(新的SomeX(){
prop1=dataRow[“someId1”],
prop2=dataRow[“someValue”]
});
}

我在上面看到的问题是很难缓存,因为所有用户可能都有唯一的列表。另一个问题是,将有大量的连接,这可能导致对数据库的大量读取。 好的是,我们可以确定在查询运行后所有信息都存在(内部连接等)

不太健谈,但仍可缓存

第三种选择可能是首先循环遍历数据行,收集所有必要的someId2,然后再发出一个数据库请求以获取所有someId2值。

“我发现上面的问题是,如果我们想要一个包含500个项目的列表,它可能会发出500个数据库请求。所有的网络延迟都是如此。”

对。还可能创建不必要的争用,并在迭代查询时消耗维护锁的服务器资源

“另一个问题是,在我们从数据库获取列表之后,但在我们试图从缓存/db获取列表之前,用户可能已被删除,这意味着我们将遇到空问题。”

如果我引用这句话,那么这句话:

“好处是它具有高度的可缓存性。”


不正确,因为您已缓存过时数据。因此,剔除目前为止唯一的优势

但要直接回答您的问题,最有效的设计(这似乎就是您要问的)是使用数据库来实现它的好处,强制执行ACID合规性和各种约束,最明显的是pk和fk,而且还用于返回聚合答案,以减少往返和应用程序端的浪费周期

这意味着你要么把SQL放进你的应用程序代码中,这被代码思想警察裁定为“无止境的低级趣味”,要么去狂欢。任何一个都可以。将代码放入应用程序可以使其更易于维护,但您将永远不会被邀请参加任何更优雅的OOP派对。

一些建议:

SQL是一种基于集合的语言,所以不要设计循环迭代。即使使用存储过程,当基于集合的查询能够解决问题时,仍然会时不时地看到游标。因此,始终尝试通过1次查询获取信息。有时候这是不可能的,但在大多数情况下,这是可能的。如果您有一个包含多个表的模式来提取一条语句所需的信息,那么您还可以设计视图以使查询更容易

使用代理。假设我有一个具有50个属性的对象。首先,向用户显示对象列表。在本例中,我将创建一个最重要属性的代理,并将其显示给用户,可能是两个或三个重要属性,如名称、ID等。这将减少最初发送的信息量。当用户实际想要编辑或更改对象时,再进行第二次查询以获取“完整”对象。只得到你需要的。当在层之间序列化XML时,这在web上尤其重要

想出一个分页策略。大多数系统工作正常,直到获得大量数据,然后查询停止,因为它正在重新生成1000个数据行/记录。尽早和经常翻页。如果您正在做一个web应用程序,那么直接在数据库中分页可能是最有效的,因为在层之间只发送分页数据

数据缓存取决于数据。对于高度易失性的数据(随时更改),缓存不值得。对于半易失性或非易失性数据,缓存是值得的,但如果使用内置框架,则必须直接或间接地管理缓存


使用缓存的一个好地方是假设您有一个邮政编码表。当然,这些不会经常更改,如果在应用程序中有邮政编码下拉列表,您可以缓存它们以提高性能。这只是一个示例,但缓存IMO取决于数据的类型。

您有没有充分的理由尝试重新设计O/RM控制盘?实体框架、NHibernate和许多其他项目已经解决了这个问题。O/R映射器有其优缺点。如果我们只想使用存储过程来运行站点,那么问题仍然存在。您能否提供一些关于数据在表中的结构的详细信息?我猜someId1表示用户id,someValue表示该用户的属性(?),这些属性存储在不同的表中。根据您的回答,重新设计几个表可能更好。“将代码放入应用程序使其更易于维护”。。什么?“不是真的,因为您缓存了过时的数据。因此,取消目前为止唯一的优势。”如果我们在数据库和缓存中处理删除/更新,我想数据不会过时。所以我仍然认为它是可缓存的