【问题标题】:How Can I Make Fast Desktop Application With Remote Database?如何使用远程数据库制作快速桌面应用程序?
【发布时间】:2014-05-13 10:17:04
【问题描述】:

我打算用 mysql 数据库制作一个桌面应用程序。我的数据库表经常变化——几乎 60% 的表。所以我认为缓存可能是一个坏主意。谁能推荐我:

如何使用远程数据库制作快速的桌面应用程序?

我的语言是 Java。

【问题讨论】:

  • 有两种方式,从应用程序的角度来看,线程会提高性能,从数据库方面,索引会提高性能,但我必须说你的问题太宽泛了。
  • 不相关说明:如果一次有多个用户访问数据库,请考虑使用 3 层架构,例如Java EE,而不是直接从 GUI 访问数据库。
  • 使用足够快的硬件,应用负载平衡,确保您没有网络瓶颈,确保您没有磁盘 I/O 瓶颈,确保您知道自己在做什么,使用数据库存储引擎和数据模型针对频繁更改进行了优化,确保配置 java 运行时以匹配您的环境,确保您的操作系统是最新的,等等。通常。对于这个广泛的问题,唯一真正的答案是“确保你以正确的思想、计划和设计来完成你的工作”。如有疑问,请聘请专家为您提供支持。
  • 不要远程连接到数据库,因为您必须将数据库密码存储在每个人都可以找到的程序中(在客户端计算机上运行时加密毫无意义)。 所以每个用户都可以访问每条数据,因为有 no row-based permissions 并且解决方法似乎增加了更多开销。
  • 什么样的数据?答案不包含太多细节的原因是问题也不包含。也许消息传递比查询更好,但如果没有您提供更多信息,就很难判断。

标签: java mysql performance desktop-application remote-server


【解决方案1】:

对于大多数以性能为主要关注点的项目来说,最大的问题是人们往往会做出一些奇特的选择,这些选择最终会使项目变得复杂而没有任何实际好处。除非您之前对将要工作的环境有实际的实践经验,否则从简单开始。

  • 设定一些现实的目标,即在开始之前刷新数据的频率。如果您的数据变化非常频繁,例如。每一秒,尝试实时显示变化是否有意义?每秒一个查询都会让参与的每个人都痛苦。

  • 使用线程来处理查询。您不需要超过一个,因为更多只会使数据库中的竞争条件变得最差。

  • 将数据库层设计为与应用程序的其余部分隔离。还要从一开始就对与数据库相关的操作进行计时,以便跟踪优化的影响。

  • 从 Hibernate / ORMLite 开始。虽然我不能谈论 ORMLite,但我已经在重负载环境中使用(优化)Hibernate,没有任何问题。如果你有复杂的对象,你应该试一试,它肯定比使用普通的 JDBC 和自己实现缓存机制要好。

  • 找出何时需要延迟加载以及何时会减慢您的速度(由于 select n+1 问题)。

  • 如果您有性能问题,请优化。您不必映射每一个关系。在单独的方法中使用自定义 SQL 以在需要时获取所需的对象。您可以编写一个只返回表 id 的查询,然后让 Hibernate 加载相应的对象。

  • 优化您的 SQL。避免连接,使用子选择,id in 等。

  • 在有意义的情况下实现(数据库)分页。

  • 如果一切都失败了,请开始使用普通 SQL。您已经编写了最复杂的查询,并且您会知道更大的瓶颈在哪里。

  • 您可以使用本地 SQLite 来保存易失性较小的数据,并主要与数据库通信以获取 id 列表和您丢失的内容。例如,如果您有用户和订单,您可以假设每分钟/秒的新订单数比每小时的用户数多得多。

总而言之,在开始之前设定明确的性能目标,始终使用单独的线程进行数据检索,避免重复发明轮子并使其尽可能简单。

【讨论】:

  • 我不知道 subselect 是否比 join 更快,因为我在大多数情况下使用 join ,无论如何这个答案对我来说是最明智的......谢谢
  • 我指的是通过使用简单的子选择和 id IN (SELECT...) 表达式可以避免连接多个表的情况。
【解决方案2】:

这里有一些通用的方法来解决这个问题。

0) 硬件:确保你的硬件没有瓶颈,你可以廉价地增加它。 (在大多数情况下,添加硬件比开发时间更快、更便宜)

1) 缓存: 也许您可以缓存(本地或在诸如 memcache 之类的分布式缓存中)往往是不可变的 40% 的数据。当数据被修改时,您可以使缓存无效。您应该选择正确的实体和粒度级别来构建密钥。

2) 复制: 如果第一个开销太大,您可以创建 mysql 的从属服务器并从那里读取。同样,您必须知道何时可以负担得起一些陈旧数据。

3) NoSQL: 朝着这个方向前进,但增加开发工作量,您可以转移到一些分布式存储(在做出选择之前先看看 CAP 定理)

希望对你有帮助

【讨论】:

    【解决方案3】:

    取决于您的数据库结构和应用程序。您可以使用ormlite 之类的对象关系映射库,并在后台使用线程刷新从数据库加载的对象。使用 ormlite,您还可以使用 LazyForeignCollection 在您的应用程序中仅加载所需的数据。

    【讨论】:

    • 我的数据库非常大,使用 ORM 对我来说太难了,因为那里有一些大查询(我们有我们的网络版本)。我认为从 ORM 很难生成复杂而大的查询 .. 我之前想的是制作一个额外的线程,该线程将获取数据并将其缓存或放入一些本地数据库,如 sqlite .. 但我不知道它是好主意还是有更好的主意
    • 您可以使用 ormlite 运行任何查询,您可以直接运行原始查询。
    • @Fisherman 将数据复制到本地数据库会导致与缓存数据相同的问题
    • @C.Champagne 另一个线程将在幕后运行。这会将远程数据库同步到本地。但由于经常更改远程数据库上的数据。可能一直在调用同步是一个坏主意,或者需要一个想法来改变这些变化。因为现在我们不会跟踪查询更改我的意思是我计划以 SQL 格式编写所有更改并且线程将在本地数据库上运行是一个好主意.. 好吧我不知道因为我不是那个经验丰富
    【解决方案4】:

    尽量减少不必要的数据库调用。

    如果您在数据库中的字段发生变化,您可以从关系数据库转移到像 MongoDB 这样的 NoSQL 数据库。

    您可以在服务器端执行多线程,用于应用服务器的数据处理和集群。在使用多线程时有效地使用它,请注意sychronized 关键字,它会在一定程度上降低性能。

    执行编码的最佳实践,不要使用更多的实例变量,尝试使用局部变量,它也会让你线程安全。

    您也可以将 Mybatis 用于 ORM 进行大型查询。

    您可以在DAO层、服务层甚至客户端进行缓存,但一定要与数据库同步,您可以使用不同的缓存解决方案。

    您可以为第一次检索进行数据库索引。

    不要使用相同的服务进行大数据查询,将其分解为不同的服务,这将有助于您以多线程方式进行处理。

    如果应用程序不是非常硬的实时系统,您也可以使用消息传递解决方案,例如异步处理数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2023-02-07
      • 2014-05-23
      相关资源
      最近更新 更多