- 浏览: 116670 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
当关系数据库试图在一个单一表中存储数 TB 的数据时,总性能经常会降低。显然,对所有数据编索引不仅对于读而且对于写都很耗时。因为 NoSQL 数据商店尤其适合存储大型数据(如 Google 的 Bigtable),显然 NoSQL 是一种非关系数据库方法。对于倾向于使用 ACID-ity 和实体结构关系数据库的开发人员及需要这种结构的项目来说,切分是一个令人振奋的可选方法。
切分是数据库分区的一个分支,但是它不是本地数据库技术 — 切分发生在应用程序级别。在各种切分实现中,Hibernate Shards 是 Java™ 技术世界中最受欢迎的一个。这个灵活绝妙的项目可以让您使用映射至逻辑数据库的 POJO 对切分数据集进行几乎无缝操作(我将在下文简要介绍 “几乎” 的原因)。使用 Hibernate Shards 时,您无须将您的 POJO 特别映射至切分 — 您可以像使用 Hibernate 方法对任何常见关系数据库进行映射时一样对其进行映射。Hibernate Shards 可以为您管理低级别的切分任务。
到目前为止,在本系列中,我已经使用了一个基于比赛和参赛者类推关系的简单域展示了各种数据库存储技术。本月,我将继续使用这个熟悉的示例介绍一种实用的切分技术,然后在 Hibernate Shards 中对其进行实现。注意:与切分相关的主要工作与 Hibernate 没有太大关系;事实上,Hibernate Shards 的编码工作比较简单。其中关键的部分在于判断如何进行切分以及对什么进行切分。
关于本系列
自 Java 技术首次诞生以来,Java 开发格局已发生了翻天覆地的变化。得益于成熟的开源框架和可靠的租赁部署基础设施,现在可以迅速而经济地组装、测试、运行和维护 Java 应用程序。在本系列中,Andrew Glover 探索使这种新的 Java 开发风格成为可能的各种技术和工具。
数据库切分是一个固有的关系流程,可以通过一些逻辑数据块将一个表的行分为不同的小组。例如,如果您正在根据时间戳对一个名为foo的超大型表进行分区,2010 年 8 月之前的所有数据都将进入分区 A,而之后的数据则全部进入分区 B。分区可以加快读写速度,因为它们的目标是单独分区中的较小型数据集。
分区功能并不总是可用的(MySQL 直到 5.1 版本后才支持),而且其需要的商业系统的成本也让人望而却步。更重要的是,大部分分区实现在同一个物理机上存储数据,所以受到硬件基础的影响。除此之外,分区也不能鉴别硬件的可靠性或者说缺乏可靠性。因此,很多智慧的人们开始寻找进行伸缩的新方法。
切分实质上是数据库级别的分区:它不是通过数据块分割数据表的行,而是通过一些逻辑数据元素对数据库本身进行分割(通常跨不同的计算机)。也就是说,切分不是将数据表分割成小块,而是将整个数据库分割成小块。
切分的一个典型示例是基于根据区域对一个存储世界范围客户数据的大型数据库进行分割:切分 A 用于存储美国的客户信息,切分 B 用户存储亚洲的客户信息,切分 C 欧洲,等。这些切分分别处于不同的计算机上,且每个切分将存储所有相关数据,如客户喜好或订购历史。
切分的好处(如分区一样)在于它可以压缩大型数据:单独的数据表在每个切分中相对较小,这样就可以支持更快速的读写速度,从而提高性能。切分还可以改善可靠性,因为即便一个切分意外失效,其他切分仍然可以服务数据。而且因为切分是在应用程序层面进行的,您可以对不支持常规分区的数据库进行切分处理。资金成本较低同样也是一个潜在优势。
像很多其他技术一样,进行切分时也需要作出部分妥协。因为切分不是一项本地数据库技术 — 也就是说,必须在应用程序中实现 —在开始切分之前需要制定出您的切分策略。进行切分时主键和跨切分查询都扮演重要角色,主要通过定义您不可以做什么实现。
主键
切分利用多个数据库,其中所有数据库都独立起作用,不干涉其他切分。因此,如果您依赖于数据库序列(如自动主键生成),很有可能在一个数据库集中将出现同一个主键。可以跨分布式数据库协调序列,但是这样会增加系统的复杂程度。避免相同主键最安全的方法就是让应用程序(应用程序将管理切分系统)生成主键。
跨切分查询
大部分切分实现(包括 Hibernate Shards)不支持跨切分查询,这就意味着,如果您想利用不同切分的两个数据集,就必须处理额外的长度。(有趣的是,Amazon 的 SimpleDB 也禁止跨域查询)例如,如果将美国客户信息存储在切分 1 中,还需要将所有相关数据存储在此。如果您尝试将那些数据存储在切分 2 中,情况就会变得复杂,系统性能也可能受影响。这种情况还与之前提到的一点有关 — 如果您因为某种原因需要进行跨切分连接,最好采用一种可以消除重复的方式管理键!
很明显,在建立数据库前必须全面考虑切分策略。一旦选择了一个特定的方向之后,您差不多就被它绑定了 — 进行切分后很难随便移动数据了。
避免不成熟切分
切分最好在后期实现。如不成熟优化一样,基于预期数据增长的切分可能是灾难的温床。成功的切分实现基于对于应用程序数据随时间增长的理解,以及之后对于未来的推断。一旦对数据进行切分后,移动数据会非常困难。
因为切分将您绑定在一个线型数据模型中(也就是说,您无法轻松连接不同切分中的数据),您必须对如何在每个切分中对数据进行逻辑组织有一个清晰的概念。这可以通过聚焦域中的主要节点实现。如在一个电子商务系统中,主要节点可以是一个订单或者一个客户。因此,如果您选择 “客户” 作为切分策略的节点,那么与客户有关的所有数据将移动至各自的切分中,但是您仍然必须选择将这些数据移动至哪个切分。
对于客户来说,您可以根据所在地(欧洲、亚洲、非洲等)切分,或者您也可以根据其他元素进行切分。这由您决定。但是,您的切分策略应该包含将数据均匀分布至所有切分的方法。切分的总体概念是将大型数据集分割为小型数据集;因此,如果一个特定的电子商务域包含一个大型的欧洲客户集以及一个相对小的美国客户集,那么基于客户所在地的切分可能没有什么意义。
现在让我们回到我经常提到的赛跑应用程序示例中,我可以根据比赛或参赛者进行切分。在本示例中,我将根据比赛进行切分,因为我看到域是根据参加不同比赛的参赛者进行组织的。因此,比赛是域的根。我也将根据比赛距离进行切分,因为比赛应用程序包含不同长度和不同参赛者的多项比赛。
请注意:在进行上述决定时,我已经接受了一个妥协:如果一个参赛者参加了不止一项比赛,他们分属不同的切分,那该怎么办呢?Hibernate Shards (像大多数切分实现一样)不支持跨切分连接。我必须忍受这些轻微不便,允许参赛者被包含在多个切分中 — 也就是说,我将在参赛者参加的多个比赛切分中重建该参赛者。
为了简便起见,我将创建两个切分:一个用于 10 英里以下的比赛;另一个用于 10 英里以上的比赛。
Hibernate Shards 几乎可以与现有 Hibernate 项目无缝结合使用。唯一问题是 Hibernate Shards 需要一些特定信息和行为。比如,需要一个切分访问策略、一个切分选择策略和一个切分处理策略。这些是您必须实现的接口,虽然部分情况下,您可以使用默认策略。我们将在后面的部分逐个了解各个接口。
执行查询时,Hibernate Shards 需要一个决定首个切分、第二个切分及后续切分的机制。Hibernate Shards 无需确定查询什么(这是 Hibernate Core 和基础数据库需要做的),但是它确实意识到,在获得答案之前可能需要对多个切分进行查询。因此,Hibernate Shards 提供了两种极具创意的逻辑实现方法:一种方法是根据序列机制(一次一个)对切分进行查询,直到获得答案为止;另一种方法是并行访问策略,这种方法使用一个线程模型一次对所有切分进行查询。
为了使问题简单,我将使用序列策略,名称为SequentialShardAccessStrategy
。我们将稍后对其进行配置。
当创建一个新对象时(例如,当通过 Hibernate 创建一个新Race
或Runner
时),Hibernate Shards 需要知道需将对应的数据写入至哪些切分。因此,您必须实现该接口并对切分逻辑进行编码。如果您想进行默认实现,有一个名为RoundRobinShardSelectionStrategy
的策略,它使用一个循环策略将数据输入切分中。
对于赛跑应用程序,我需要提供根据比赛距离进行切分的行为。因此,我们需要实现ShardSelectionStrategy
接口并提供依据Race
对象的distance
采用selectShardIdForNewObject
方法进行切分的简易逻辑。(我将稍候在Race
对象中展示。)
运行时,当在我的域对象上调用某一类似save
的方法时,该接口的行为将被深层用于 Hibernate 的核心。
import org.hibernate.shards.ShardId; import org.hibernate.shards.strategy.selection.ShardSelectionStrategy; public class RacerShardSelectionStrategy implements ShardSelectionStrategy { public ShardId selectShardIdForNewObject(Object obj) { if (obj instanceof Race) { Race rce = (Race) obj; return this.determineShardId(rce.getDistance()); } else if (obj instanceof Runner) { Runner runnr = (Runner) obj; if (runnr.getRaces().isEmpty()) { throw new IllegalArgumentException("runners must have at least one race"); } else { double dist = 0.0; for (Race rce : runnr.getRaces()) { dist = rce.getDistance(); break; } return this.determineShardId(dist); } } else { throw new IllegalArgumentException("a non-shardable object is being created"); } } private ShardId determineShardId(double distance){ if (distance > 10.0) { return new ShardId(1); } else { return new ShardId(0); } } } |
如您在清单 1中所看到的,如果持久化对象是一场Race
,那么其距离被确定,而且(因此)选择了一个切分。在这种情况下,有两个切分:0 和 1,其中切分 1 中包含 10 英里以上的比赛,切分 0 中包含所有其他比赛。
如果持久化一个Runner
或其他对象,情况会稍微复杂一些。我已经编码了一个逻辑规则,其中有三个原则:
- 一名
Runner
在没有对应的Race
时无法存在。 - 如果
Runner
被创建时参加了多场Race
s,这名Runner
将被持久化到寻找到的首场Race
所属的切分中。(顺便说一句,该原则对未来有负面影响。) - 如果还保存了其他域对象,现在将引发一个异常。
然后,您就可以擦掉额头的热汗了,因为大部分艰难的工作已经搞定了。随着比赛应用程序的增长,我所使用的逻辑可能会显得不够灵活,但是它完全可以顺利地完成这次演示!
当通过键搜索一个对象时,Hibernate Shards 需要一种可以决定首个切分的方法。将需要使用SharedResolutionStrategy
接口对其进行指引。
如我之前提到的那样,切分迫使您重视主键,因为您将需要亲自管理这些主键。幸运的是,Hibernate 在提供键或 UUID 生成方面表现良好。因此 Hibernate Shards 创造性地提供一个 ID 生成器,名为ShardedUUIDGenerator
,它可以灵活地将切分 ID 信息嵌入到 UUID 中。
如果您最后使用ShardedUUIDGenerator
进行键生成(我在本文中也将采取这种方法),那么您也可以使用 Hibernate Shards 提供的创新ShardResolutionStrategy
实现,名为AllShardsShardResolutionStrategy
,这可以决定依据一个特定对象的 ID 搜索什么切分。
配置好 Hibernate Shards 工作所需的三个接口后,我们就可以对切分示例应用程序的第二步进行实现了。现在应该启动 Hibernate 的SessionFactory
了。
Hibernate 的其中一个核心接口对象是它的SessionFactory
。Hibernate 的所有神奇都是在其配置 Hibernate 应用程序过程中通过这个小对象实现的,例如,通过加载映射文件和配置。如果您使用了注释或 Hibernate 珍贵的 .hbm 文件,那么您还需要一个SessionFactory
来让 Hibernate 知道哪些对象是可以持久化的,以及将它们持久化到哪里。
因此,使用 Hibernate Shards 时,您必须使用一个增强的SessionFactory
类型来配置多个数据库。它可以被命名为ShardedSessionFactory
,而且它当然是SessionFactory
类型的。当创建一个ShardedSessionFactory
时,您必须提供之前配置好的三个切分实现类型(ShardAccessStrategy
、ShardSelectionStrategy
和ShardResolutionStrategy
)。您还需提供 POJO 所需的所有映射文件。(如果您使用一个基于备注的 Hibernate POJO 配置,情况可能会有所不同。)最后,一个ShardedSessionFactory
示例需要每个切分都对应多个 Hibernate 配置文件。
我已经创建了一个ShardedSessionFactoryBuilder
类型,它有一个主要方法createSessionFactory
,可以创建一个配置合理的SessionFactory
。之后,我将将所有的一切都与 Spring 连接在一起(现在谁不使用一个 IOC 容器?)。现在,清单 2 显示了ShardedSessionFactoryBuilder
的主要作用:创建一个 Hibernate配置
:
private Configuration getPrototypeConfig(String hibernateFile, List<String> resourceFiles) { Configuration config = new Configuration().configure(hibernateFile); for (String res : resourceFiles) { configs.addResource(res); } return config; } |
如您在清单 2中所看到的,可以从 Hibernate 配置文件中创建了一个简单的Configuration
。该文件包含如下信息,如使用的是什么类型的数据库、用户名和密码等,以及所有必须的资源文件,如 POJO 所用的 .hbm 文件。在进行切分的情况下,您通常需要使用多个数据库配置,但是 Hibernate Shards 支持您仅使用一个 hibernate.cfg.xml 文件,从而简化了整个过程(但是,如您在清单 4中所看到的,您将需要对使用的每一个切分准备一个 hibernate.cfg.xml 文件)。
下一步,在清单 3 中,我将所有的切分配置都收集到了一个List
中:
List<ShardConfiguration> shardConfigs = new ArrayList<ShardConfiguration>(); for (String hibconfig : this.hibernateConfigurations) { shardConfigs.add(buildShardConfig(hibconfig)); } |
在清单 3中,对hibernateConfigurations
的引用指向了String
sList
,其中每个 String 都包含了 Hibernate 配置文件的名字。该List
通过 Spring 自动连接。清单 4 是我的 Spring 配置文件中的一段摘录:
<bean id="shardedSessionFactoryBuilder" class="org.disco.racer.shardsupport.ShardedSessionFactoryBuilder"> <property name="resourceConfigurations"> <list> <value>racer.hbm.xml</value> </list> </property> <property name="hibernateConfigurations"> <list> <value>shard0.hibernate.cfg.xml</value> <value>shard1.hibernate.cfg.xml</value> </list> </property> </bean> |
如您在清单 4中所看到的,ShardedSessionFactoryBuilder
正在与一个 POJO 映射文件和两个切分配置文件连接。清单 5 中是 POJO 文件的一段摘录:
<class name="org.disco.racer.domain.Race" table="race"dynamic-update="true" dynamic-insert="true"> <id name="id" column="RACE_ID" unsaved-value="-1"> <generator class="org.hibernate.shards.id.ShardedUUIDGenerator"/> </id> <set name="participants" cascade="save-update" inverse="false" table="race_participants" lazy="false"> <key column="race_id"/> <many-to-many column="runner_id" class="org.disco.racer.domain.Runner"/> </set> <set name="results" inverse="true" table="race_results" lazy="false"> <key column="race_id"/> <one-to-many class="org.disco.racer.domain.Result"/> </set> <property name="name" column="NAME" type="string"/> <property name="distance" column="DISTANCE" type="double"/> <property name="date" column="DATE" type="date"/> <property name="description" column="DESCRIPTION" type="string"/> </class> |
请注意,清单 5中的 POJO 映射的唯一独特方面是 ID 的生成器类 — 这就是ShardedUUIDGenerator
,它(如您想象的一样)将切分 ID 信息嵌入到 UUID 中。这就是我的 POJO 映射中切分的唯一独特方面。
下一步,如清单 6 中所示,我已经配置了一个切分 — 在本示例中,除切分 ID 和连接信息外,切分 0 和切分 1 的文件是一样的。
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="HibernateSessionFactory0"> <property name="dialect">org.hibernate.dialect.HSQLDialect</property> <property name="connection.driver_class">org.hsqldb.jdbcDriver</property> <property name="connection.url"> jdbc:hsqldb:file:/.../db01/db01 </property> <property name="connection.username">SA</property> <property name="connection.password"></property> <property name="hibernate.connection.shard_id">0</property> <property name="hibernate.shard.enable_cross_shard_relationship_checks">true </property> </session-factory> </hibernate-configuration> |
如其名字所示,enable_cross_shard_relationship_checks
属性对跨切分关系进行了检查。根据 Hibernate Shards 文档记录,该属性非常耗时,在生成环境中应该关闭。
最后,ShardedSessionFactoryBuilder
通过创建ShardStrategyFactory
,然后添加三个类型(包括清单 1中的RacerShardSelectionStrategy
),将一切都整合到了一起,如清单 7 中所示:
private ShardStrategyFactory buildShardStrategyFactory() { ShardStrategyFactory shardStrategyFactory = new ShardStrategyFactory() { public ShardStrategy newShardStrategy(List<ShardId> shardIds) { ShardSelectionStrategy pss = new RacerShardSelectionStrategy(); ShardResolutionStrategy prs = new AllShardsShardResolutionStrategy(shardIds); ShardAccessStrategy pas = new SequentialShardAccessStrategy(); return new ShardStrategyImpl(pss, prs, pas); } }; return shardStrategyFactory; } |
最后,我执行了那个名为createSessionFactory
的绝妙方法,在本示例中创建了一个ShardedSessionFactory
,如清单 8 所示:
public SessionFactory createSessionFactory() { Configuration prototypeConfig = this.getPrototypeConfig (this.hibernateConfigurations.get(0), this.resourceConfigurations); List<ShardConfiguration> shardConfigs = new ArrayList<ShardConfiguration>(); for (String hibconfig : this.hibernateConfigurations) { shardConfigs.add(buildShardConfig(hibconfig)); } ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory(); ShardedConfiguration shardedConfig = new ShardedConfiguration( prototypeConfig, shardConfigs,shardStrategyFactory); return shardedConfig.buildShardedSessionFactory(); } |
现在可以深呼吸一下了,因为我们马上就成功了。到目前为止,我已经创建一个可以合理配置ShardedSessionFactory
的生成器类,其实就是实现 Hibernate 无处不在的SessionFactory
类型。ShardedSessionFactory
完成了切分中所有的神奇。它利用我在清单 1中所部署的切分选择策略,并从我配置的两个切分中读写数据。(清单 6显示了切分 0 和切分 1 的配置几乎相同。)
现在我需要做的就是连接我的域对象,在本示例中,因为它们依赖于 Hibernate,需要一个SessionFactory
类型进行工作。我将仅使用我的ShardedSessionFactoryBuilder
提供一种SessionFactory
类型,如清单 9 中所示:
<bean id="mySessionFactory" factory-bean="shardedSessionFactoryBuilder" factory-method="createSessionFactory"> </bean> <bean id="race_dao" class="org.disco.racer.domain.RaceDAOImpl"> <property name="sessionFactory"> <ref bean="mySessionFactory"/> </property> </bean> |
如您在清单 9中所看到的,我首先在 Spring 中创建了一个类似工厂的 bean;也就是说,我的RaceDAOImpl
类型有一个名为sessionFactory
的属性,是SessionFactory
类型。之后,mySessionFactory
引用通过在ShardedSessionFactoryBuilder
上调用createSessionFactory
方法创建了一个SessionFactory
示例,如清单 4中所示。
当我为我的Race
对象示例使用 Spring(我主要将其作为一个巨型工厂使用,以返回预配置的对象)时,一切事情就都搞定了。虽然没有展示,RaceDAOImpl
类型是一个利用 Hibernate 模板进行数据存储和检索的对象。我的Race
类型包含一个RaceDAOImpl
示例,它将所有与数据商店相关的活动都推迟至此。很默契,不是吗?
请注意,我的 DAO 与 Hibernate Shards 在代码方面并没有绑定,而是通过配置进行了绑定。配置(如清单 5中的)将它们绑定在一个特定切分 UUID 生成方案中,也就是说了我可以在需要切分时从已有 Hibernate 实现中重新使用域对象。
接下来,我需要验证我的切分实现可以工作。我有两个数据库并通过距离进行切分,所以当我创建一场马拉松时(10 英里以上的比赛),该Race
示例应在切分 1 中找到。一个小型的比赛,如 5 公里的比赛(3.1 英里),将在切分 0 中找到。创建一场Race
后,我可以检查单个数据库的记录。
在清单 10 中,我已经创建了一场马拉松,然后继续验证记录确实是在切分 1 中而非切分 0 中。使事情更加有趣(和简单)的是,我使用了 easyb,这是一个基于 Groovy 的行为驱动开发架构,利用自然语言验证。easyb 也可以轻松处理 Java 代码。即便不了解 Groovy 或 easyb,您也可以通过查看清单 10 中的代码,看到一切如期进行。(请注意,我帮助创建了 easyb,并且在 developerWorks 中对这个话题发表过文章。)
scenario "races greater than 10.0 miles should be in shard 1 or db02", { given "a newly created race that is over 10.0 miles", { new Race("Leesburg Marathon", new Date(), 26.2, "Race the beautiful streets of Leesburg!").create() } then "everything should work fine w/respect to Hibernate", { rce = Race.findByName("Leesburg Marathon") rce.distance.shouldBe 26.2 } and "the race should be stored in shard 1 or db02", { sql = Sql.newInstance(db02url, name, psswrd, driver) sql.eachRow("select race_id, distance, name from race where name=?", ["Leesburg Marathon"]) { row -> row.distance.shouldBe 26.2 } sql.close() } and "the race should NOT be stored in shard 0 or db01", { sql = Sql.newInstance(db01url, name, psswrd, driver) sql.eachRow("select race_id, distance, name from race where name=?", ["Leesburg Marathon"]) { row -> fail "shard 0 contains a marathon!" } sql.close() } } |
当然,我的工作还没有完 — 我还需要创建一个短程比赛,并验证其位于切分 0 中而非切分 1 中。您可以在本文提供的代码下载中看到该验证操作!
切分可以增加应用程序的读写速度,尤其是如果您的应用程序包含大量数据 — 如数 TB — 或者您的域处于无限制发展中,如 Google 或 Facebook。
在进行切分之前,一定要确定应用程序的规模和增长对其有利。切分的成本(或者说缺点)包括对如何存储和检索数据的特定应用程序逻辑进行编码的成本。进行切分后,您多多少少都被锁定在您的切分模型中,因为重新切分并非易事。
如果能够正确实现,切分可以用于解决传统 RDBMS 规模和速度问题。切分对于绑定于关系基础架构、无法继续升级硬件以满足大量可伸缩数据存储要求的组织来说是一个非常成本高效的决策。
源码下载地址:http://www.ibm.com/developerworks/apps/download/index.jsp?contentid=551775&filename=j-javadev2-11.zip&method=http&locale=zh_CN
发表评论
-
Google公开Megastore论文——解决NoSQL、SQL融合难题
2011-03-02 14:44 671实际上,作为一个建 ... -
开源数据库Sharding技术
2011-03-02 16:14 714内容摘要:Sharding 不是一个某个特定数据库软件附 ... -
可扩展的分布式数据库架构
2011-03-03 14:44 684本文发表在《程序员 ... -
OLTP系统与DSS系统对比
2011-03-03 15:35 653在进行数据库系统的设计时,一个不可忽视的问题是弄清你所 ... -
Oracle高级复制机制
2011-03-10 15:48 660Oracle高级复制即可支 ... -
Oracle高级复制的同步复制的配置步骤说明
2011-03-10 15:50 833以下的文章主要讲述的是Oracle高级复制的同步复制,如 ... -
linux oracle中文乱码问题解决方法
2011-04-11 15:18 773connect system/oracle9i ... -
ubuntu下安装ocfs2
2011-07-12 14:20 977简介 一个集群文件系统能使运行在集群中所有节点并发的通过 ... -
asm下载地址
2011-07-12 16:50 898asm rpm包下载地址http://www.oracle.c ... -
oracle重要初始参数
2011-09-28 17:15 872OPEN_CURSORS session可以打开的游标最大数, ... -
SQLJ是什么?优点?
2011-10-11 09:56 915SQLJ是一种允许把静态的SQL语句以文本形式嵌入Java程序 ... -
共享池的调整与优化(Shared pool Tuning)
2011-10-11 10:53 737共享池(Shared pool)是SGA中最关键的内存片段,共 ... -
使用DBMS_SHARED_POOL包将PL/SQL大对象保存到Shared Pool
2011-10-11 16:32 733当系统在加载PL/SQL大对象时,有可能遭遇由于SharedP ... -
oracle sga相关
2011-10-12 17:08 840oracle主要影响性能的内存: Shared ... -
oracle内存调整相关
2011-10-14 15:52 891db_cache_size与sga_target关系 db_ ... -
oracle索引分类
2011-10-17 13:31 856B-TREE INDEX,B树索引:在创建索引时他是 ... -
修改oracle redo log的大小
2011-10-17 15:53 11111.查看现在的REDO GRO ... -
本地管理表空间
2011-10-18 13:29 762本地管理表空间的好处: 1:快速,并发空间操作 ... -
Oracle表空间命令
2011-10-19 16:55 798创建立表空间 CREATE TABLESPACE ... -
Oracle 索引组织表(IOT)
2011-10-28 09:16 808索引组织表(IOT)有一种类B树的存储组织方法。普通的堆组织表 ...
相关推荐
本文档主要讨论了 Java 开发 2.0 中的数据库切分技术,特别是使用 Hibernate Shards 实现数据库切分。文章首先介绍了数据库切分的概念和优点,接着讨论了 Hibernate Shards 的使用方法和优点。最后,文章还讨论了...
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用
## 1、数据简介 国家农业龙头企业数量主要指的是经过国家相关部门认定,并在农业产业化方面发挥重要引领作用的企业的总数。这些企业通常以农产品加工或流通为主业,通过各种利益联结机制与农户相联系,带动农户进入市场,实现农产品生产、加工、销售的有机结合和相互促进。 数据名称:国家农业龙头企业数量 数据年份:2010-2022年 ## 02、相关数据 省份、年份、龙头企业数量。
这是一个二手车交易信息网站,用struts2+spring+mybites写的,数据库放在webContent目录下的。.zip项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款
本系统是集工单统计、任务钩子、权限管理、灵活配置流程与模版等等于一身的开源工单系统,当然也可以称之为工作流引擎。 致力于减少跨部门之间的沟通,自动任务的执行,提升工作效率与工作质量,减少不必要的工作量与人为出错率。
第00卷,密码在对应的文章内。
目录: linuxmint-15-cinnamon-dvd-32bit linuxmint-15-cinnamon-dvd-64bit linuxmint-15-kde-dvd-32bit linuxmint-15-kde-dvd-64bit linuxmint-15-mate-dvd-32bit linuxmint-15-mate-dvd-64bit linuxmint-15-xfce-dvd-32bit linuxmint-15-xfce-dvd-64bit 网盘文件永久链接
chromedriver-win32-135.0.7031.0(Canary).zip
STM32开发:IIR带阻滤波器设计与实现,含巴特沃斯和切比雪夫滤波器MATLAB程序,STM32开发中IIR带阻滤波器的实现与巴特沃斯滤波器设计详解:附MATLAB程序,STM32开发 IIR带阻滤波器 STM32实现IIR无限冲击响应带阻滤波器设计,巴特沃斯滤波器,代码工整,自编代码,注释详细,赠送巴特沃斯和切比雪夫IIR带阻滤波器MATLAB程序 ,STM32开发; IIR带阻滤波器; 无限冲击响应; 巴特沃斯滤波器; 自编代码; 注释详细; MATLAB程序,STM32中IIR带阻滤波器设计与实现
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用
纯电动汽车仿真研究:基于Matlab Simulink与Simscape的车辆模型动力性、经济性及续航里程分析,基于Matlab Simulink与Simscape的纯电动汽车动力、经济性及续航里程仿真模型探究,纯电动汽车仿真、纯电动公交、纯电动客车、纯电动汽车动力性仿真、经济性仿真、续航里程仿真。 模型包括电机、电池、车辆模型。 有两种模型2选1: 1 完全用matlab simulink搭建的模型。 2用simscape搭建的车辆模型。 ,纯电动汽车仿真; 纯电动公交; 纯电动客车; 动力性仿真; 经济性仿真; 续航里程仿真; 模型(电机、电池、车辆模型); MATLAB Simulink模型; Simscape车辆模型。,纯电动交通工具仿真模型研究:基于Matlab Simulink与Simscape的电池、电机及车辆性能分析
MATLAB代码:电转气P2G与碳捕集设备在热电联供综合能源系统中的优化调度模型研究:融入碳交易机制的非线性模型高效求解。,MATLAB环境下结合P2G技术与碳捕集设备的综合能源系统优化调度模型,包括热电联产与低碳调度,借鉴碳交易机制实现高效求解。,MATLAB代码:考虑P2G和碳捕集设备的热电联供综合能源系统优化调度模型 注意:店铺内有大量考虑碳交易代码,欢迎咨询 关键词:碳捕集 综合能源系统 电转气P2G 热电联产 低碳调度 参考文档:《Modeling and Optimization of Combined Heat and Power with Power-to-Gas and Carbon Capture System in Integrated Energy System》完美复现 仿真平台:MATLAB yalmip+gurobi 主要内容:代码主要做的是一个考虑电转气P2G和碳捕集设备的热电联供综合能源系统优化调度模型,模型耦合CHP热电联产单元、电转气单元以及碳捕集单元,并重点考虑了碳交易机制,建立了综合能源系统运行优化模型,模型为非线性模型,采用yalmip
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用,资源为网络商品(电子资料类)基于网络商品和电子资料商品的性质和特征不支持退款,质量优质,放心下载使用
19考试真题最近的t37.txt
MATLAB交通标志识别系统可以通过图像处理和机器学习技术来识别道路上的不同交通标志。这个系统可以通过以下步骤来实现: 1. **数据收集**:收集具有不同交通标志的图像作为训练集,可以使用公开的交通标志数据集或者自己创建一个数据集。 2. **图像预处理**:对采集到的图像进行预处理,比如去噪、调整大小、灰度化等操作,以便更好地进行特征提取。 3. **特征提取**:从预处理后的图像中提取特征,例如颜色、形状、纹理等特征,以便训练分类器。 4. **分类器训练**:使用机器学习算法(如支持向量机、人工神经网络等)对提取的特征进行训练,以建立交通标志的分类模型。 5. **标志识别**:使用训练好的分类器对新的图像进行识别,并输出识别结果。 MATLAB提供了丰富的图像处理工具箱和机器学习工具箱,可以帮助实现交通标志识别系统。可以使用MATLAB编写代码来处理图像、提取特征、训练分类器和进行识别。同时,也可以借助深度学习工具箱来构建卷积神经网络(CNN)等深度学习模型进行交通标志的识别。 需要注意的是,在实际应用中,还需要考虑系统的实时性、准确性和稳定性等因素,以确保该系统在不同场景下能够有效地识别交通标志。
双有源桥扩展技术:100kHz高频率、最小电流应力优化的3kw功率开关控制系统,双有源桥扩展技术:100kHz高频率、375-48V宽电压范围下的3kw功率控制与优化,双有源桥扩展移相控制 开关频率100k,375-48V,功率3kw 控制方式为最小电流应力优化控制 参数可定制 ,双有源桥;扩展移相控制;开关频率100k;功率3kw;最小电流应力优化控制;参数可定制,双桥移相控制,最小电流应力优化——100k开关频率功率控制技术
基于粒子群算法的IEEE30节点输电网最优潮流研究:以系统发电成本最小化为目标的二次函数关系优化求解,基于粒子群算法的输电网最优潮流控制研究:以IEEE30节点系统为例,探讨发电成本最小化及机组出力优化,基于粒子群算法的最优潮流 以IEEE30节点的输电网为研究对象 以系统发电成本最小为目标函数 以机组出力为优化变量 其中出力与成本的关系是经典的二次函数关系 通过优化求解得到最佳机组出力 ,最优潮流;粒子群算法;IEEE30节点输电网;系统发电成本;机组出力优化;二次函数关系;优化求解。,基于粒子群算法的IEEE30节点输电网最优潮流研究:成本最小化与机组出力优化
Abaqus管中管系统深水管非线性动力分析:Tube-to-Tube ITT单元的应用研究,Abaqus软件在管中管系统深水管非线性动力分析中的应用:基于Tube-to-tube ITT单元的数值模拟研究,abaqus 管中管系统 深水管非线性动力分析 Tube-to-tube ITT单元 ,Abaqus; 管中管系统; 深水管非线性动力分析; ITT单元; 节点分析; 仿真建模。,Abaqus深水管非线性动力分析中管中管系统的ITT单元应用
springboot在线知识管理平台类智慧交通调度平台源码+论文+视频1