Skip to content

Commit 59d781f

Browse files
author
holbrook
committed
add
1 parent 9a5fb71 commit 59d781f

File tree

3 files changed

+268
-0
lines changed

3 files changed

+268
-0
lines changed

WQTA1.pdf

131 Bytes
Binary file not shown.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"hexo-renderer-markdown-it-plus": "^1.0.2",
1818
"hexo-renderer-stylus": "^0.3.1",
1919
"hexo-server": "^0.2.0",
20+
"hexo-tag-echarts3": "^1.1.2",
2021
"hexo-tag-plantuml": "^1.0.0",
2122
"hexo-viz": "^0.1.0",
2223
"markdown-it-katex": "^2.0.3"

source/_drafts/Charts-test.md

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
---
2+
title: ECharts测试
3+
postslug: charts_test
4+
date: 2018-11-01
5+
category: demo
6+
tags: dmeo
7+
---
8+
9+
10+
# 关系数据库,数据文件 还是 NoSQL
11+
12+
股票行情数据具有如下特点:
13+
14+
1. 数据量大
15+
16+
对于分析来说,至少需要5分钟数据。如果每天交易时间为4小时,每年250个交易日,则一支股票一年的行情数据量为60/5*4*250= 12k。20年则为240k。如果是1分钟数据,则20年的数据量为240k*5 = 1.2M。
17+
18+
所以,如果用于分析,行情数据将是百万量级。如果记录3000只股票/指数的数据,数据量会非常大。
19+
20+
2. 数据很少变化
21+
22+
由于都是历史数据,行情数据很少需要修改。主要的操作是查询和增加。
23+
24+
3. 数据结构简单
25+
26+
主要考虑[成交数据](/2013/12/18/quotation_model.html#menuIndex2),是一种简单的一维结构。价格数据只在发生交易信号时有一定的参考意义,不需要保留所有的历史记录。
27+
28+
由于行情数据的这些特点,通常不适合使用关系数据库。传统上一般采用数据文件进行存储。
29+
30+
但是用数据文件需要自己处理写入锁,随机读写,序列化等问题,比较麻烦。于是[NoSQL](/2013/12/18/nosql_list.html#menuIndex1)成了比较好的一种选择。
31+
32+
对于单机的分析软件,[NoSQL选型要素](/2013/12/18/nosql_list.html#menuIndex2)为:
33+
34+
- key/value儲存
35+
- 支持持久化
36+
- 支持嵌入式
37+
- 接口方便
38+
39+
# Oracle Berkeley DB
40+
41+
[Berkeley DB](http://www.oracle.com/technetwork/cn/products/berkeleydb/overview/index.html)是满足上述4点要求的比较好的一款产品。Berkeley DB分为BDB、BDB Java版和BDB XML版。其总体架构如下图:
42+
43+
{% asset_img berkeley-db.png Berkeley DB %}
44+
45+
BDB的三个版本的功能不完全相同。
46+
47+
48+
我选择BDB Java版,不支持SQL API和XQuery API,可以使用底层的键/值API、Java 直接持久层 (DPL) API和Java 集合 API。三种API的应用场景如下:
49+
50+
51+
- 当 Java 类是用来代表应用中的域对象(___domain objects),也就是说,该模式是相对 稳定的,建议用直接持久层。
52+
- 当在Berkeley DB和Berkeley DB Java 版之间移植应用程序时,或当实现自己的 动态模式(举例来说,一个 LDAP 服务器),那么建议用基础 API。您也可能喜欢使用这 个基础API如果您有极少数域类(___domain class)。
53+
- 集合API有利于和外部组件交互,因为它遵从Java集合框架标准。继而,和基础API 以及直接持久层结合后会很有用。您可能会喜欢这个 API,因为它提供了熟悉的 Java 集 合接口。
54+
55+
在行情数据的持久化中,可以选用直接持久层(DPL)。直接持久层API 可以持久化以及还原相互关联的 Java 对象,但是比ORM更加简单高效。
56+
57+
# 实现过程
58+
59+
## 获取开发包
60+
61+
可以从[这里](http://www.oracle.com/technetwork/cn/products/berkeleydb/downloads/index.html)下载需要的jar包,也可以使用maven:
62+
63+
```
64+
<dependency>
65+
<groupId>com.sleepycat</groupId>
66+
<artifactId>je</artifactId>
67+
<version>5.0.73</version>
68+
</dependency>
69+
70+
```
71+
72+
如果要使用最新版(目前的最新版是5.0.97),需要引入oracle的maven库:
73+
74+
```
75+
<repositories>
76+
<repository>
77+
<id>oracleReleases</id>
78+
<name>Oracle Released Java Packages</name>
79+
<url>http://download.oracle.com/maven</url>
80+
<layout>default</layout>
81+
</repository>
82+
</repositories>
83+
```
84+
85+
86+
## 定义持久化模型
87+
88+
### 实体和值对象
89+
90+
Berkeley DB支持DDD(领域驱动设计)中的实体和值对象的持久化。
91+
92+
- 实体:拥有长期不变的标识符,可以被跟踪的对象。
93+
- 值对象:没有标识符,主要关注其属性的对象。
94+
95+
在BDB中,分别使用 **@Entity****@Persistent** 来声明实体和值对象。
96+
声明了 **@Persistent** 的对象可以直接作为 **@Entity** 对象中的属性使用。
97+
98+
任何Java类一旦增加了持久化声明,其所有字段(任何作用域)都会被持久化。需要持久化的类需要缺省的无参数构造函数。
99+
100+
比如:
101+
102+
103+
```
104+
105+
@Entity
106+
public class Transaction {
107+
……
108+
public OHLC ohlc;
109+
……
110+
}
111+
112+
113+
@Persistent
114+
public class OHLC {
115+
public float open,high,low,close;
116+
}
117+
118+
```
119+
120+
121+
### 主键和“次键”声明
122+
123+
每个实体类(@Entity)可以定义一个主键(PrimaryKey)和多个次键(SecondaryKey),从而可以按照主键或次键进行索引。例如:
124+
125+
```
126+
127+
@Entity
128+
public class Security implements Instrument{
129+
@PrimaryKey
130+
private String code;
131+
132+
@SecondaryKey(relate=Relationship.ONE_TO_ONE)
133+
private String name;
134+
……
135+
}
136+
```
137+
138+
### 关联关系
139+
140+
关联关系也是通过次键(SecondaryKey)声明的。需要同时指定多重性(relate)和关联到的实体(relatedEntity)。
141+
relate可以是ONE_TO_ONE,ONE_TO_MANY,MANY_TO_ONE或MANY_TO_MANY(在com.sleepycat.persist.model.Relationship中定义)。
142+
143+
需要注意的是,次键的属性类型需要是relatedEntity指定的对端实体的主键类型,而不能直接使用对端实体。
144+
145+
如果relate是ONE_TO_MANY或MANY_TO_MANY,可以使用集合类型。比如(不属于股票行情数据模型,而是BDB官方例子):
146+
147+
```
148+
149+
@Entity
150+
class Employer {
151+
@PrimaryKey(sequence="ID")
152+
long id;
153+
154+
@SecondaryKey(relate=ONE_TO_ONE) String name;
155+
……
156+
}
157+
158+
159+
@Entity
160+
class Person {
161+
@PrimaryKey
162+
String ssn;
163+
164+
@SecondaryKey(relate=MANY_TO_ONE, relatedEntity=Person.class)
165+
String parentSsn;
166+
167+
@SecondaryKey(relate=ONE_TO_MANY)
168+
Set<String> emailAddresses = new HashSet<String>();
169+
170+
@SecondaryKey(relate=MANY_TO_MANY, relatedEntity=Employer.class, onRelatedEntityDelete=NULLIFY)
171+
Set<Long> employerIds = new HashSet<Long>();
172+
……
173+
}
174+
175+
```
176+
177+
178+
179+
## 使用DPL API
180+
181+
### 设计Accessor(TODO)
182+
183+
类似于DAO,BDB中通常将对实体的访问封装到Accessor中。例如:
184+
185+
1. EntityStore
186+
187+
2. 获取索引
188+
189+
3. CRUD
190+
191+
4. 访问关联对象
192+
193+
通过索引可以得到关联的对象,无论是单个关联对象还是集合。
194+
195+
- 关联到单个对象
196+
- 关联到集合
197+
198+
```
199+
EntityCursor<Person> employees = dao.personByEmployerIds.subIndex(gizmoInc.id).entities();
200+
try {
201+
for (Person employee : employees) {
202+
System.out.println(employee.ssn + ' ' + employee.name); }
203+
} finally {
204+
employees.close();
205+
}
206+
```
207+
208+
- 等值连接
209+
210+
通过 EntityJoin 类可以进行等值连 接(equality join)操作。
211+
212+
比如,以下代码查询所有Bob的孩子中为gizmo公司工作的 员工:
213+
214+
```
215+
EntityJoin<String,Person> join = new EntityJoin(dao.personBySsn);
216+
join.addCondition(dao.personByParentSsn, "111-11-1111"); join.addCondition(dao.personByEmployerIds, gizmoInc.id);
217+
ForwardCursor<Person> results = join.entities(); try {
218+
for (Person person : results) { System.out.println(person.ssn + ' ' + person.name);
219+
}
220+
} finally {
221+
results.close();
222+
}
223+
```
224+
225+
### 建立连接
226+
227+
### 事务支持
228+
229+
```
230+
Transaction txn = env.beginTransaction(null, null); dao.employerById.put(txn, gizmoInc); dao.employerById.put(txn, gadgetInc);
231+
txn.commit();
232+
```
233+
234+
### 模型变化
235+
236+
对于增加实体或值对象的属性,改变属性类型等变化,一般不需要对BDB进行额外的处理,而是会自动适应。
237+
238+
对于一些特殊的、无法自动适应的变化,比如重命名字段或优化单个的类(如:使用通用类型,模块复用等改变),可以使用Mutations。
239+
240+
Mutations 操作是延迟的:只在存取数据时自动改变,故避免了软件升级时大型数据库转换导致的长时间停机。
241+
复杂的类优化可能涉及到多个类,使用 ConversionStore 进行。因而,无论持久化类作出何种 改变,直接持久层都始终提供可靠数据存取。
242+
243+
### 性能选项
244+
245+
Berkeley DB在API的很多地方提供了性能调优的选项。常见的包括:
246+
247+
- DatabaseConfig参数
248+
249+
通过DatabaseConfig参数可以用来调整Berkeley DB引擎的性能。
250+
比如,可指定内部B树节点的大小来调整性能,通过如下方式来指定:
251+
252+
```
253+
DatabaseConfig config = store.getPrimaryConfig(Employer.class);
254+
config.setNodeMaxEntries(64);
255+
store.setPrimaryConfig(config);
256+
```
257+
258+
- CRUD操作参数
259+
260+
例如, “脏读”可通过LockMode参数实现:
261+
262+
263+
Employer employer = employerByName.get(null, "Gizmo Inc", LockMode.READ_UNCOMMITTED);
264+
265+
266+
267+

0 commit comments

Comments
 (0)