為快速高維OLAP實現殼片段shell-fragment的方法(具體實現)
本文目錄結構
資料儲存
為方便程式的讀取,同時節約記憶體開支,我把儲存在csv檔案中的資料讀入資料庫,在資料庫中建立oriTable用來存放原始表格資料。
索引建立
原始索引
通過一遍掃描(按列掃描),為原始資料表中的部分欄位(根據資料特點和具體的需要進行選取)建立索引。並且在相同資料庫下為每一個欄位建立一張表,用來存放該欄位下全部資料的倒排索引表。
殼片段的完全資料立方體的倒排索引
對每一個片段(egA1,A2,A3),需要對它的每一個方體(eg A1,A2)的每一個單元(eg,1/0,0/0,1/1,1/0)計算倒排索引表,對每一個單元,記錄它關聯的TID列表。並存入資料庫。
在殼片段計算完成之後,處理點查詢和子立方體查詢。
對於點查詢
首先對查詢語句進行處理,劃分成殼片段的部分和單一維度的部分,對於“*”由於是不相關的,把它視為孤立的單一維度,並且不對它進行處理。
對於子立方體查詢
把?詢問的維度看作是單一維度,對於它的每一個值,分別與其他的各個例示的值組成一條點查詢。如果有兩個或者三個問號,則需要進行交叉。這個就把一個複雜問題分解成了許多個可以handle的小問題。
下面是一些技術細節(附程式碼)
1.我的專案目錄結構:
簡要介紹一下每一個類的功能。
其實我覺得我的命名很規範,算了,不介紹了。給你個眼神你自己體會。
DataToDB(將csv檔案中的原始資料 寫到資料庫中去)
表是我手動建立的,核心還是呼叫了DBU的插入函式。
package com.chang;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
public class DataToDB {
public static ArrayList<String> readCsv(String filepath) {
File csv = new File(filepath); // CSV檔案路徑
csv.setReadable(true);// 設定可讀
csv.setWritable(true);// 設定可寫
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(csv));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = "";
String everyLine = "";
ArrayList<String> allString = new ArrayList<>();
try {
while ((line = br.readLine()) != null) // 讀取到的內容給line變數
{
everyLine = line;
allString.add(everyLine);
}
System.out.println("csv表格中所有行數:" + allString.size());
} catch (IOException e) {
e.printStackTrace();
}
return allString;
}
//前提是先在資料庫中建立好了表。
public static void main(String[] args) {
System.out.println("hello");
ArrayList<String> arrayList = new ArrayList<>();
// .\代表當前路徑
arrayList = readCsv("./resourse\\employees.csv");
//獲取到列名陣列。
String col_names = arrayList.remove(0);
String[] col_names_array = col_names.split(",");
System.out.println(Arrays.toString(col_names_array));
int i=0;
for (String str : arrayList) {
// System.out.println(str);
i++;
String[] values_array =str.split(",");
System.out.println(Arrays.toString(values_array));
DBUtil.insert("ori_table", col_names_array, values_array);
System.out.println(i);
}
}
}
效果如下圖:
DBUtil.java (資料庫互動)
其中在建立表之前,加入了判斷,如果已經存在同名的表,那麼將同名的表刪除掉。在select函式取資料的時候,怎麼都取不出來,後來發現是因為數字作欄位名,需要數字兩邊加上``。還有一個獲取表的列名的函式,用的地方其實挺多,挺有用的。由於存放殼片段產生的索引的需要,我在DBUtil中加入了一個建表的函式,輸入是表名和欄位名的陣列,輸出當然是資料庫裡的一張表啦,不太好的是這個函式被我寫死了,因為是用來存長長的索引串的,所以一律採用longtext儲存。
package com.chang;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Properties;
import com.mysql.cj.jdbc.PreparedStatement;
import com.mysql.cj.jdbc.result.ResultSetMetaData;
public class DBUtil {
private static String dbDriver = "com.mysql.cj.jdbc.Driver";
private static String dbUrl;
private static String dbUser;
private static String dbPass;
public static boolean config(String mysqlURL, String mysqlUserName, String mysqlPassword) {
try {
Class.forName(dbDriver);
} catch (ClassNotFoundException e) {
System.err.println(e);
return false;
}
dbUrl = mysqlURL;
dbUser = mysqlUserName;
dbPass = mysqlPassword;
System.out.println("URL:" + dbUrl);
System.out.println("UserName:" + dbUser);
System.out.println("Password:" + dbPass);
try {
Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
conn.close();
} catch (SQLException e) {
System.err.println(e);
dbUrl = null;
dbPass = null;
dbUser = null;
return false;
}
return true;
}
public static Connection getConn() {
try {
Class.forName(dbDriver);
} catch (ClassNotFoundException e) {
System.err.println(e);
return null;
}
Connection conn;
if (dbUrl == null || dbUser == null || dbPass == null) {
Properties prop = new Properties();
try {
prop.load(DBUtil.class.getResourceAsStream("/application.properties"));
} catch (IOException e) {
System.err.println(e);
return null;
}
dbUrl = prop.getProperty("mysqlURL");
dbUser = prop.getProperty("mysqlUserName");
dbPass = prop.getProperty("mysqlPassword");
}
try {
conn = DriverManager.getConnection(dbUrl, dbUser, dbPass);
} catch (SQLException e) {
System.err.println(e);
return null;
}
return conn;
}
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/*
* @param tableName,the target parameters,the parameter values
*
* @return flag(true->success)
*/
public static boolean insert(String table, String[] params, String[] params_value) {
boolean flag = true;
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
String sql = "insert into " + table + " (";
for (int i = 0; i < params.length - 1; i++) {
sql += "`" + params[i] + "`" + ",";
}
sql += "`" + params[params.length - 1] + "`" + ") values (";
for (int j = 0; j < params_value.length - 1; j++) {
sql += "'" + params_value[j] + "' ,";
}
sql += "'" + params_value[params_value.length - 1] + "');";
try {
conn = getConn();
try {
st = (PreparedStatement) conn.prepareStatement(sql);
} catch (SQLException e) {
flag = false;
e.printStackTrace();
}
try {
st.executeUpdate();
} catch (SQLException e) {
flag = false;
e.printStackTrace();
}
} finally {
release(conn, st, rs);
}
return flag;
}
/*
* select {params} from table
*/
public static String[][] select(String table, String[] params) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
String[][] result = null;
String sql = "select ";
for (int i = 0; i < params.length - 1; i++) {
sql +="`"+ params[i] +"`"+ ",";
}
sql +="`"+ params[params.length - 1] + "`"+" from " + table;
try {
conn = getConn();
try {
st = (PreparedStatement) conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
try {
rs = st.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
java.sql.ResultSetMetaData mm = null;
try {
mm = rs.getMetaData();
} catch (SQLException e1) {
e1.printStackTrace();
}
int columns = 0;
try {
columns = mm.getColumnCount();
} catch (SQLException e1) {
e1.printStackTrace();
}
int rowCount = 0;
try {
rs.last();
rowCount = rs.getRow();
} catch (Exception e) {
e.printStackTrace();
}
try {
rs.beforeFirst();
} catch (SQLException e1) {
e1.printStackTrace();
}
int k = 0;
try {
result = new String[rowCount][columns];
while (rs.next()) {
for (int i = 1; i <= columns; i++) {
try {
result[k][i - 1] = rs.getString(i);
} catch (SQLException e) {
e.printStackTrace();
}
}
k++;
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
} finally {
release(conn, st, rs);
}
}
/**
* 建立表
*
* @param tabName
* 表名稱
* @param tab_fields
* 表字段
*/
public static void createTableOri(String tabName, String[] tab_fields) {
// 首先要獲取連線,即連線到資料庫
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConn();
String sql = "create table " + tabName + "(id int auto_increment primary key not null";
if (tab_fields != null && tab_fields.length > 0) {
sql += ",";
int length = tab_fields.length;
for (int i = 0; i < length; i++) {
// 新增欄位
sql += tab_fields[i].trim() + " varchar(50)";
// 防止最後一個,
if (i < length - 1) {
sql += ",";
}
}
}
// 拼湊完 建表語句 設定預設字符集
sql += ")DEFAULT CHARSET=utf8;";
// System.out.println("建表語句是:" + sql);
ps = (PreparedStatement) conn.prepareStatement(sql);
ps.executeUpdate(sql);
ps.close();
conn.close(); // 關閉資料庫連線
} catch (SQLException e) {
System.out.println("建表失敗" + e.getMessage());
}
}
public static void createTable(String tabName, String[] tab_fields) {
// 首先要獲取連線,即連線到資料庫
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConn();
String sql = "create table " + tabName + "(";
if (tab_fields != null && tab_fields.length > 0) {
int length = tab_fields.length;
for (int i = 0; i < length; i++) {
// 新增欄位
sql += "`" + tab_fields[i].trim() + "`" + " longtext";
// 防止最後一個,
if (i < length - 1) {
sql += ",";
}
}
}
// 拼湊完 建表語句 設定預設字符集
sql += ");";
// System.out.println("建表語句是:" + sql);
ps = (PreparedStatement) conn.prepareStatement(sql);
ps.executeUpdate(sql);
ps.close();
conn.close(); // 關閉資料庫連線
} catch (SQLException e) {
System.out.println("建表失敗" + e.getMessage());
}
}
相關推薦
為快速高維OLAP實現殼片段shell-fragment的方法(初步設想)
初步設想
把資料存入資料庫。額,怎麼也插不進去,最後發現,left這個欄位名不被接受,有可能是和mysql的關鍵字衝突了,所以不被允許,改了之後就可以了。
如何為每一個維集合也就是每一個片段計算立方體呢?根據每一個維的每一個值的倒排索引表唄。倒排索引表以字串的格式存在數組裡。物化
為快速高維OLAP實現殼片段shell-fragment的方法(具體實現)
本文目錄結構
資料儲存
索引建立
原始索引
殼片段的完全資料立方體的倒排索引
在殼片段計算完成之後,處理點查詢和子立方體查詢。
對於點查詢
對於子立方體查詢
下面是一些技術細節(附程式
如何快速通過url定位到controller中的方法(採用AOP)
aspect 攔截controller顯示指明
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotat
Android Studio 快速實現上傳專案到Github(詳細步驟)
前言:
本文主要講解如何將Android Studio專案上傳至GitHub,在此之前,先介紹幾個概念。
Android Studio:是谷歌推出一個Android整合開發工具,基於IntelliJ IDEA,類似 Eclipse ADT,Android Studio 提供了整合的 Android 開發工具用
【面試題】實現一個棧,要求Push(入棧),Pop(出棧),Min(返回最小值的操作)的時間複雜度為O(1)
問題描述:實現一個棧,要求Push(入棧),Pop(出棧),Min(返回最小值的操作)的時間複雜度為O(1)
分析問題:要記錄從當前棧頂到棧底元素的最小值,很容易想到用一個變數,每push一個元素更新一次變數的值。那麼問題來了,當執行pop操作時,上一次的最小值就找不到
[演算法入門]快速排序非遞迴方法(Java實現),大家一起來找茬啊~
基礎
總結一下,快速排序的步驟:
1、找到一個key值(就是陣列第一個值),先從右到左找,找到一個比它小的值,記錄下標。
2、然後從左往右找,找到一個比它大的值,記錄下標。
3、交換找到的兩個數
騰訊面試題:模板實現一個棧,要求Push(入棧),Pop(出棧),Max(返回最大值的操作)的時間複雜度為O(1)
解題思路:要用模板實現亂序入棧的陣列每次pop()出棧都能得到當前棧中Max的最大值,就必須在push()入棧時進行維護操作,使的每次入棧的元素都能夠找到合適的位置並push(),每次push()操作完成後棧中的元素都能夠按從棧頂到棧底從大到小排列即可。這就需要寫一個不同於常
Nginx實現七層的負載均衡(LB Nginx)
lb nginx
Nginx實現七層的負載均衡調度到不同組後端服務器1. 動靜分離2. 網站進行分區=================================================================================拓撲結構
【LeetCode-面試算法經典-Java實現】【130-Surrounded Regions(圍繞區域)】
pos apt pub iso all 左面 ons || title
【130-Surrounded Regions(圍繞區域)】
【LeetCode-面試算法經典-Java實現】【全部題目文件夾索引】
原題
Given a 2D b
【LeetCode-面試算法經典-Java實現】【054-Spiral Matrix(螺旋矩陣)】
[] -a order detail tty util lis title comment
【054-Spiral Matrix(螺旋矩陣)】
【LeetCode-面試算法經典-Java實現】【全部題目文件夾索引】
原題
Given a
C語言實現單鏈表節點的刪除(帶頭結點)
data art pos grand urn ria tps move sni
我在之前一篇博客《C語言實現單鏈表節點的刪除(不帶頭結點)》中具體實現了怎樣在一個不帶頭結點的單鏈表的刪除一個節點,在這一篇博客中我改成了帶頭結點的單鏈表。代碼演示樣例上傳至 h
【LeetCode-面試算法經典-Java實現】【066-Plus One(加一)】
ext javascrip ide new dig lis leetcode .net store
【066-Plus One(加一)】
【LeetCode-面試算法經典-Java實現】【全部題目文件夾索引】
原題
Given a no
【LeetCode-面試算法經典-Java實現】【139-Word Break(單詞拆分)】
put art als min 全部 detail set 長度 trac
【139-Word Break(單詞拆分)】
【LeetCode-面試算法經典-Java實現】【全部題目文件夾索引】
原題
Given a string s a
C語言實現單鏈表的節點插入(帶頭結點)
alloc tails 函數 file ret con 實現 單獨 fun
我在之前一篇博客《C語言實現單鏈表(不帶頭結點)節點的插入》中具體實現了怎樣在一個不帶頭結點的單鏈表中進行節點的插入。可是在實際應用中,帶頭結點的鏈表更為經常使用。更為方便。今天我們
【LeetCode-面試算法經典-Java實現】【062-Unique Paths(唯一路徑)】
ade ssi comment span there sdn href func 圖片
【062-Unique Paths(唯一路徑)】
【LeetCode-面試算法經典-Java實現】【全部題目文件夾索引】
原題
A robot is
ViewPager,實現真正的無限循環(定時+手動)
pre san fcm drawable size 消息 water selected nts 利用定時器,實現循環輪播,很簡單;只需在定時器的消息裏加如下代碼即可:
int count = adapter.getCount();
if (count >
css實現垂直水平居中的方法(個數不限)?
實現 容易 css3 pre height blog pad 絕對定位 fresh 方法一:使用絕對定位
大家都知道margin:0 auto;能夠實現水平居中,但卻不知道margin:0 auto;也是可以實現垂直居中的;
給居中元素添加如下樣式:
Shell編程(轉—總結)
bsp shel sed 正則表達式 grep 字符處理 進行 總結 正則 一、基礎正則表達式
1、正則表達式與通配符
正則表達式:用來在文件中匹配符合條件的字符串,正則是包含匹配,grep、awk、sed等命令支持正則表達式
c#實現圖片二值化例子(黑白效果)
rec con devel 圖片 round amp bsp 操作 spl C#將圖片2值化示例代碼,原圖及二值化後的圖片如下: 原圖: 二值化後的圖像: 實現代碼:using System;
using System.Drawing;
namespace BMP2G
WebAPI Ajax 跨域請求解決方法(CORS實現)
custom XML header 就會 情況 取數 -o cross serve 概述
ASP.NET Web API 的好用使用過的都知道,沒有復雜的配置文件,一個簡單的ApiController加上需要的Action就能工作。
但是在使用API的時候總會遇到跨