Dou*_*oug 16 java mysql arrays varchar blob
我有一个设计决定,我正在寻找一些最佳实践建议.我有一个java程序,需要在MySQL数据库中存储大量(每天几百个)浮点数组.数据是一个长度Double
为300 的固定长度数组.我可以看到三个合理的选项:
我还要提一下,这些数据将被频繁地读取和更新.
我想使用BLOB,因为这是我过去所做的,它似乎是最有效的方法(例如,保持固定宽度,不需要转换为逗号分隔的字符串).然而,我的同事坚持认为我们应该序列化和使用varchar,原因似乎主要是教条.
如果其中一种方法比另一种更好,那么Java或MySQL的具体原因是什么?
Bil*_*win 14
您是否有理由不创建子表,以便每行存储一个浮点值而不是数组?
假设您每天存储一千个300个元素的数组.这是每天300,000行,或每年1.095亿行.没有什么可以打喷嚏,但在MySQL或任何其他RDBMS的能力范围内.
你的意见:
当然,如果订单很重要,您可以为订单添加另一列.这是我设计表格的方式:
CREATE TABLE VectorData (
trial_id INT NOT NULL,
vector_no SMALLINT UNSIGNED NOT NULL,
order_no SMALLINT UNSIGNED NOT NULL,
element FLOAT NOT NULL,
PRIMARY KEY (trial_id, vector_no),
FOREIGN KEY (trial_id) REFERENCES Trials (trial_id)
);
Run Code Online (Sandbox Code Playgroud)
一行矢量数据的总空间:300x(4 + 2 + 2 + 4)= 3600字节.加上InnoDB记录目录(内部东西)的16个字节.
如果序列化300个浮点数= 1227个字节的Java数组,则总空间是多少?
因此,通过存储阵列可节省大约2400字节或67%的空间.但假设您有100GB的空间来存储数据库.存储序列化数组允许存储8750万个向量,而标准化设计仅允许存储2980万个向量.
你说你每天存储几百个向量,所以你只需要在81年而不是239年内填充100GB的分区.
重新评论:INSERT的性能是一个重要的问题,但你每天只存储几百个向量.
大多数MySQL应用程序每秒可以实现数百或数千个插入,而无需过多的魔法.
如果您需要最佳性能,请参阅以下内容:
在您最喜爱的搜索引擎上搜索短语"每秒插入一次mysql",阅读许多文章和博客,并谈论这一点.
像这样存储BLOB(参见下面的代码示例).我认为这可能比使用java序列化更好,因为java的内置序列化将需要2427个字节,非Java应用程序将更难处理数据.也就是说,如果将来有任何非Java应用程序查询数据库......如果没有,那么内置序列化就少了几行.
public static void storeInDB() throws IOException, SQLException {
double[] dubs = new double[300];
ByteArrayOutputStream bout = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(bout);
for (double d : dubs) {
dout.writeDouble(d);
}
dout.close();
byte[] asBytes = bout.toByteArray();
PreparedStatement stmt = null; // however we normally get this...
stmt.setBytes(1, asBytes);
}
public static double[] readFromDB() throws IOException, SQLException {
ResultSet rs = null; // however we normally get this...
while (rs.next()) {
double[] dubs = new double[300];
byte[] asBytes = rs.getBytes("myDoubles");
ByteArrayInputStream bin = new ByteArrayInputStream(asBytes);
DataInputStream din = new DataInputStream(bin);
for (int i = 0; i < dubs.length; i++) {
dubs[i] = din.readDouble();
}
return dubs;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我希望使用BINARY(2400),但MySQL说:
mysql> create table t (a binary(2400)) ;
ERROR 1074 (42000): Column length too big for column 'a' (max = 255);
use BLOB or TEXT instead
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13968 次 |
最近记录: |