Skip to content

Commit 0878b17

Browse files
committed
smlar
1 parent d0aa585 commit 0878b17

14 files changed

+1917
-0
lines changed

201502/20150228_01.md

Lines changed: 435 additions & 0 deletions
Large diffs are not rendered by default.

201502/20150228_01_pic_001.png

4.31 KB
Loading

201502/readme.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### 文章列表
2+
----
3+
##### 20150228_01.md [《PostgreSQL 统计信息之 - 逻辑与物理存储的线性相关性》](20150228_01.md)

201604/20160403_01.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
## PostgreSQL 计算 任意类型 字段之间的线性相关性
2+
3+
### 作者
4+
digoal
5+
6+
### 日期
7+
2016-04-03
8+
9+
### 标签
10+
PostgreSQL , 线性相关性
11+
12+
----
13+
14+
## 背景
15+
PostgreSQL自带了计算numeric和numeric字段的线性相关性的聚合函数corr(numeric, numeric)。
16+
17+
例如:
18+
19+
```
20+
postgres=# select corr(c1,c2) from (values (1,2),(2,1),(100,90),(13,13),(25,27) ) t(c1,c2);
21+
corr
22+
-------------------
23+
0.998528203831946
24+
(1 row)
25+
26+
postgres=# \df+ corr
27+
List of functions
28+
Schema | Name | Result data type | Argument data types | Type | Security | Volatility | Owner | Language | Source code | Description
29+
------------+------+------------------+------------------------------------+------+----------+------------+----------+----------+-----------------+-------------------------
30+
pg_catalog | corr | double precision | double precision, double precision | agg | invoker | immutable | postgres | internal | aggregate_dummy | correlation coefficient
31+
(1 row)
32+
```
33+
34+
如果要计算多元的线性相关性,可以使用madlib提供的linregr_train函数来统计。
35+
36+
http://doc.madlib.net/latest/group__grp__linreg.html
37+
38+
注意不管是一元回归还是多元回归,都需要提供数字类型,如果是文本是不支持的,如下:
39+
40+
```
41+
postgres=# select corr(c1,c3) from (values (1,2,'test'),(2,1,'digoal'),(100,90,'hello'),(13,13,'china'),(25,27,'hangzhou') ) t(c1,c2,c3);
42+
ERROR: function corr(integer, text) does not exist
43+
LINE 1: select corr(c1,c3) from (values (1,2,'test'),(2,1,'digoal'),...
44+
^
45+
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
46+
```
47+
48+
那么怎么处理呢?
49+
50+
PostgreSQL提供了强大的窗口功能,因为任意字段都可以排序,所以只要使用窗口输出字段排序后的rank()就可以代表它的位置从而计算相关性。
51+
52+
例如
53+
54+
```
55+
postgres=# select
56+
c1, rank() over(order by c1) rc1,
57+
c2, rank() over(order by c2) rc2,
58+
c3, rank() over(order by c3) rc3
59+
from (values (1,2,'test'),(2,1,'digoal'),(100,90,'hello'),(13,13,'china'),(25,27,'hangzhou') )
60+
t(c1,c2,c3) order by c1;
61+
c1 | rc1 | c2 | rc2 | c3 | rc3
62+
-----+-----+----+-----+----------+-----
63+
1 | 1 | 2 | 2 | test | 5
64+
2 | 2 | 1 | 1 | digoal | 2
65+
13 | 3 | 13 | 3 | china | 1
66+
25 | 4 | 27 | 4 | hangzhou | 3
67+
100 | 5 | 90 | 5 | hello | 4
68+
(5 rows)
69+
```
70+
71+
这个例子要计算c1,c3的相关性,c1是数字字段,但是c3是text。 corr函数不支持这么操作。
72+
73+
因此我使用上面这条带窗口的SQL,把text字段根据rank抽象为数值,正好和其他字段可以匹配相关性。
74+
75+
来看计算结果:
76+
77+
```
78+
postgres=# select corr(c1,rc3), corr(rc1,rc3) from (
79+
select
80+
c1, rank() over(order by c1) rc1,
81+
c2, rank() over(order by c2) rc2,
82+
c3, rank() over(order by c3) rc3
83+
from (values (1,2,'test'),(2,1,'digoal'),(100,90,'hello'),(13,13,'china'),(25,27,'hangzhou')
84+
) t(c1,c2,c3)
85+
) t;
86+
corr | corr
87+
-------------------+------
88+
0.283302495025433 | -0.1
89+
(1 row)
90+
```
91+
92+
建议采用corr(rc1,rc3)的结果,这个比较有代表性。 代表被评测列的线性相关性。
93+
94+
应用场景大家猜一猜。
95+
96+
[Count](http://info.flagcounter.com/h9V1)
97+
98+

201604/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### 文章列表
22
----
33
##### 20160401_01.md [《阿里云 PostgreSQL pg_hint_plan插件的用法》](20160401_01.md)
4+
##### 20160403_01.md [《PostgreSQL 计算 任意类型 字段之间的线性相关性》](20160403_01.md)
45
##### 20160414_01.md [《PostgreSQL 物联网黑科技 - 瘦身几百倍的索引(BRIN index)》](20160414_01.md)
56
##### 20160419_01.md [《PostgreSQL 行级 全文检索》](20160419_01.md)
67
##### 20160426_01.md [《iperf 测试网络性能指标》](20160426_01.md)

201701/20170116_01.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
## 数据库小程序 - 广播(notify/listen)
2+
3+
### 作者
4+
digoal
5+
6+
### 日期
7+
2017-01-16
8+
9+
### 标签
10+
PostgreSQL , notify , listen , 异步消息
11+
12+
----
13+
14+
## 背景
15+
小时候就梦想有个酷酷的电波表(虽然现在还没有拥有),不过电波表和PostgreSQL有什么关系呢?听我道来。
16+
17+
![pic](20170116_01_pic_001.jpg)
18+
19+
http://baike.baidu.com/view/1124741.htm
20+
21+
电波表内置高感度小型天线,接收标准电波进行自动对时,因而可以实现时间上的精准。在国际上,德国、英国、美国、日本都已经有标准电波的发送。2007年7月,在中国河南商丘建成的新电波塔已经开始发送电波。
22+
23+
标准电波接收(6局电波接收)原理
24+
25+
中国标准时间以10万年误差1秒的铯原子钟为基准。通过手表内置的高敏感度接收器接收以无线电波传送的标准时间信号,并自动校准手表走时。使手表显示的时间与标准时间同步,精确计时。在建筑物密集的室内也可以接收标准电波信号,显示正确的时间。
26+
27+
标准电波的接收范围是半径约1000~3000km, 深夜(最多6次)自动接收电波信号,不能收到标准电波信号时,自动接收GPS卫星电波获取时间信息并校正时间。中国的电波塔在河南省商丘市。
28+
29+
而用于接收电波信号的防震天线采用的是非晶材质,能够实现高敏感度接收。不但具备对应极端户外环境下使用的牢靠性,还可以确保稳定接收全球6局电波信号。
30+
31+
电波表是一个非常典型的广播应用,类似的还有组播(注意不是主播哦),类似的应用也很多,比如广播电视,电台等。
32+
33+
## 数据库广播
34+
在数据库中,其实也有类似的应用,比如我前几天在文章中写的数据库到WEB客户端的广播,详见 :
35+
36+
[《从微信小程序 到 数据库"小程序" , 鬼知道我经历了什么》](./20170113_03.md)
37+
38+
实际上是利用了PostgreSQL数据库的异步消息机制,数据库往消息通道发送数据,应用程序可以监听对应的消息通道,获取数据库发出的数据。
39+
40+
通过异步消息在数据库中实现了一对多的广播效果。
41+
42+
SQL语法参考文档:
43+
44+
1\. 向通道发送消息
45+
46+
https://www.postgresql.org/docs/9.6/static/sql-notify.html
47+
48+
2\. 监听某通道的消息
49+
50+
https://www.postgresql.org/docs/9.6/static/sql-listen.html
51+
52+
3\. 取消监听某通道
53+
54+
https://www.postgresql.org/docs/9.6/static/sql-unlisten.html
55+
56+
4\. 数据库函数
57+
58+
查看会话监听了哪些通道,以及当前数据库的异步消息队列使用了多少。
59+
60+
```
61+
pg_listening_channels() setof text channel names that the session is currently listening on
62+
pg_notification_queue_usage() double fraction of the asynchronous notification queue currently occupied (0-1)
63+
```
64+
65+
pg_notification_queue_usage用来计算已使用的异步消息页面占比,如果有监听,但是一直不消费,可能导致溢出。
66+
67+
```
68+
src/backend/commands/async.c
69+
70+
/*
71+
* slru.c currently assumes that all filenames are four characters of hex
72+
* digits. That means that we can use segments 0000 through FFFF.
73+
* Each segment contains SLRU_PAGES_PER_SEGMENT pages which gives us
74+
* the pages from 0 to SLRU_PAGES_PER_SEGMENT * 0x10000 - 1.
75+
*
76+
* It's of course possible to enhance slru.c, but this gives us so much
77+
* space already that it doesn't seem worth the trouble.
78+
*
79+
* The most data we can have in the queue at a time is QUEUE_MAX_PAGE/2
80+
* pages, because more than that would confuse slru.c into thinking there
81+
* was a wraparound condition. With the default BLCKSZ this means there
82+
* can be up to 8GB of queued-and-not-read data.
83+
*
84+
* Note: it's possible to redefine QUEUE_MAX_PAGE with a smaller multiple of
85+
* SLRU_PAGES_PER_SEGMENT, for easier testing of queue-full behaviour.
86+
*/
87+
#define QUEUE_MAX_PAGE (SLRU_PAGES_PER_SEGMENT * 0x10000 - 1)
88+
89+
90+
src/include/access/slru.h:#define SLRU_PAGES_PER_SEGMENT 32
91+
```
92+
93+
## 异步消息编程
94+
除了使用SQL来编写异步消息,还可以使用数据库的驱动来编写异步消息
95+
96+
### c
97+
参考libpq的异步消息部分
98+
99+
https://www.postgresql.org/docs/9.6/static/libpq-notify.html
100+
101+
```
102+
PGnotify *PQnotifies(PGconn *conn);
103+
104+
typedef struct pgNotify
105+
{
106+
char *relname; /* notification channel name */
107+
int be_pid; /* process ID of notifying server process */
108+
char *extra; /* notification payload string */
109+
} PGnotify;
110+
```
111+
112+
文档中有一个例子如下
113+
114+
https://www.postgresql.org/docs/9.6/static/libpq-example.html#LIBPQ-EXAMPLE-2
115+
116+
117+
### java
118+
参考文档
119+
120+
https://jdbc.postgresql.org/documentation/head/listennotify.html
121+
122+
### 应用举例
123+
Broadcasting PostgreSQL NOTIFY messages to WebSocket Clients
124+
125+
The system works like this:
126+
127+
```
128+
Client subscribes to a WebSocket topic...
129+
130+
NOTIFY event on database server ->
131+
PGNotificationListener on web server ->
132+
Send Websocket notification on server ->
133+
Receive Websocket event on browser.
134+
```
135+
136+
With the code below, if you call NOTIFY dml_events, 'some message'; in Postgres, it will be broadcast to all WebSocket clients.
137+
138+
Follow this [answer](https://bitbucket.org/neilmcg/postgresql-websocket-example) regarding proper listener setup
139+
140+
URL:
141+
142+
http://blog.databasepatterns.com/2014/04/postgresql-nofify-websocket-spring-mvc.html
143+
144+
http://stackoverflow.com/questions/37916489/listen-notify-pgconnection-goes-down-java
145+
146+
```
147+
The notification listeners are internally maintained by that library as weak references meaning that you have to hold a hard reference externally so they won't be garbage collected.
148+
Check out the BasicContext class lines 642 - 655:
149+
150+
---
151+
public void addNotificationListener(String name, String channelNameFilter, NotificationListener listener) {
152+
153+
name = nullToEmpty(name);
154+
channelNameFilter = channelNameFilter != null ? channelNameFilter : ".*";
155+
156+
Pattern channelNameFilterPattern = Pattern.compile(channelNameFilter);
157+
158+
NotificationKey key = new NotificationKey(name, channelNameFilterPattern);
159+
160+
synchronized (notificationListeners) {
161+
notificationListeners.put(key, new WeakReference<NotificationListener>(listener));
162+
}
163+
164+
}
165+
---
166+
167+
If the GC picks up your listener, calls to "get" on the weak reference will return null and will not fire as seen from lines 690 - 710
168+
169+
---
170+
@Override
171+
public synchronized void reportNotification(int processId, String channelName, String payload) {
172+
173+
Iterator<Map.Entry<NotificationKey, WeakReference<NotificationListener>>> iter = notificationListeners.entrySet().iterator();
174+
while (iter.hasNext()) {
175+
176+
Map.Entry<NotificationKey, WeakReference<NotificationListener>> entry = iter.next();
177+
178+
NotificationListener listener = entry.getValue().get();
179+
if (listener == null) {
180+
181+
iter.remove();
182+
}
183+
else if (entry.getKey().channelNameFilter.matcher(channelName).matches()) {
184+
185+
listener.notification(processId, channelName, payload);
186+
}
187+
188+
}
189+
190+
}
191+
---
192+
193+
To fix this, add your notification listeners as such:
194+
195+
---
196+
/// Do not let this reference go out of scope!
197+
PGNotificationListener listener = new PGNotificationListener() {
198+
199+
@Override
200+
public void notification(int processId, String channelName, String payload) {
201+
// interesting code
202+
};
203+
pgConnection.addNotificationListener(listener);
204+
---
205+
206+
Quite an odd use-case for weak references in my opinion...
207+
```
208+
209+
代码:
210+
211+
https://bitbucket.org/neilmcg/postgresql-websocket-example
212+
213+
其他编程语言的驱动,大多数是基于libpq的,不再举例。
214+
215+
## 参考
216+
217+
[《从微信小程序 到 数据库"小程序" , 鬼知道我经历了什么》](./20170113_03.md)
218+
219+
220+
221+
[Count](http://info.flagcounter.com/h9V1)
222+

201701/20170116_01_pic_001.jpg

31.7 KB
Loading

0 commit comments

Comments
 (0)