一尘不染

BLOB与VARCHAR用于在MySQL表中存储数组

mysql

我要做出设计决定,正在寻找一些最佳实践建议。我有一个Java程序,需要在MySQL数据库中存储大量(每天数百个)浮点数组。数据是长度Double为300
的固定长度数组。我可以看到三个合理的选择:

  1. 将数据存储为BLOB。
  2. 序列化数据并将其存储为VARCHAR。
  3. 将数据作为二进制文件写入磁盘,并存储对它的引用。

我还应该提到,该数据将被读取并经常更新。

我想使用BLOB,因为这是我过去所做的,并且这似乎是最有效的方法(例如,保持固定宽度且无需转换为逗号分隔的字符串)。但是,我的同事坚持认为,我们应该序列化和使用varchar,其原因似乎主要是教条主义的。

如果这些方法中的一种优于另一种,那么原因是Java还是MySQL特定?


阅读 237

收藏
2020-05-17

共1个答案

一尘不染

像这样存储为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;
    }

}

编辑:我希望使用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
2020-05-17