2010-12-08 4 views
41

Ich verwende eine Postgresql-Datenbank in meiner Rails-Anwendung. Um große Dateien oder Daten in der Datenbank zu speichern, habe ich den Blob-Datentyp in MySql verwendet.Wie verwende ich den Blob-Datentyp in Postgres

Für Postgres welcher Datentyp muss ich anstelle von Blob in MySql verwenden?

Danke!

Antwort

35

Verwendung bytea (oder Large Objects wenn Sie absolutely have to)

+1

warum sagst du "wenn du unbedingt musst"? Sehen Sie große Nachteile bei der Verwendung von Large Objects? – avernet

+1

@avernet - ja, sie sind schwieriger zu arbeiten und hatten [einige Sicherheitsprobleme] (http://doc.postgresintl.com/jdbc/ch08.html) –

+0

Danke, das ist sehr wertvolle Informationen. – avernet

2

Necromancing. Nur zu Ihrer Information: Speichern von Dateien in Ihrer Datenbank wird zu einer riesigen Datenbankgröße führen.Sie mögen das nicht mögen, für die Entwicklung, Tests, Backups usw.

Stattdessen würden Sie FileStream (SQL-Server) oder BFILE (Oracle) verwenden.

Es gibt keine Standard-Implementierung von BFILE/Filestream in Postgre, aber Sie können es hinzufügen: https://github.com/darold/external_file

und weitere Informationen (wenn Sie französisch, sonst viel Glück mit Google-translate sprechen) hier erhalten werden kann :
http://blog.dalibo.com/2015/01/26/Extension_BFILE_pour_PostgreSQL.html


Um die aktuelle Frage zu beantworten:
Neben bytea, für wirklich große Dateien, können Sie LOBS verwenden:

// http://stackoverflow.com/questions/14509747/inserting-large-object-into-postgresql-returns-53200-out-of-memory-error 
// https://github.com/npgsql/Npgsql/wiki/User-Manual 
public int InsertLargeObject() 
{ 
    int noid; 
    byte[] BinaryData = new byte[123]; 

    // Npgsql.NpgsqlCommand cmd ; 
    // long lng = cmd.LastInsertedOID; 

    using (Npgsql.NpgsqlConnection connection = new Npgsql.NpgsqlConnection(GetConnectionString())) 
    { 
     using (Npgsql.NpgsqlTransaction transaction = connection.BeginTransaction()) 
     { 
      try 
      { 
       NpgsqlTypes.LargeObjectManager manager = new NpgsqlTypes.LargeObjectManager(connection); 
       noid = manager.Create(NpgsqlTypes.LargeObjectManager.READWRITE); 
       NpgsqlTypes.LargeObject lo = manager.Open(noid, NpgsqlTypes.LargeObjectManager.READWRITE); 

       // lo.Write(BinaryData); 
       int i = 0; 
       do 
       { 
        int length = 1000; 
        if (i + length > BinaryData.Length) 
         length = BinaryData.Length - i; 

        byte[] chunk = new byte[length]; 
        System.Array.Copy(BinaryData, i, chunk, 0, length); 
        lo.Write(chunk, 0, length); 
        i += length; 
       } while (i < BinaryData.Length); 

       lo.Close(); 
       transaction.Commit(); 
      } // End Try 
      catch 
      { 
       transaction.Rollback(); 
       throw; 
      } // End Catch 

      return noid; 
     } // End Using transaction 

    } // End using connection 

} // End Function InsertLargeObject 



public System.Drawing.Image GetLargeDrawing(int idOfOID) 
{ 
    System.Drawing.Image img; 

    using (Npgsql.NpgsqlConnection connection = new Npgsql.NpgsqlConnection(GetConnectionString())) 
    { 
     lock (connection) 
     { 
      if (connection.State != System.Data.ConnectionState.Open) 
       connection.Open(); 

      using (Npgsql.NpgsqlTransaction trans = connection.BeginTransaction()) 
      { 
       NpgsqlTypes.LargeObjectManager lbm = new NpgsqlTypes.LargeObjectManager(connection); 
       NpgsqlTypes.LargeObject lo = lbm.Open(takeOID(idOfOID), NpgsqlTypes.LargeObjectManager.READWRITE); //take picture oid from metod takeOID 
       byte[] buffer = new byte[32768]; 

       using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 
       { 
        int read; 
        while ((read = lo.Read(buffer, 0, buffer.Length)) > 0) 
        { 
         ms.Write(buffer, 0, read); 
        } // Whend 

        img = System.Drawing.Image.FromStream(ms); 
       } // End Using ms 

       lo.Close(); 
       trans.Commit(); 

       if (connection.State != System.Data.ConnectionState.Closed) 
        connection.Close(); 
      } // End Using trans 

     } // End lock connection 

    } // End Using connection 

    return img; 
} // End Function GetLargeDrawing 



public void DeleteLargeObject(int noid) 
{ 
    using (Npgsql.NpgsqlConnection connection = new Npgsql.NpgsqlConnection(GetConnectionString())) 
    { 
     if (connection.State != System.Data.ConnectionState.Open) 
      connection.Open(); 

     using (Npgsql.NpgsqlTransaction trans = connection.BeginTransaction()) 
     { 
      NpgsqlTypes.LargeObjectManager lbm = new NpgsqlTypes.LargeObjectManager(connection); 
      lbm.Delete(noid); 

      trans.Commit(); 

      if (connection.State != System.Data.ConnectionState.Closed) 
       connection.Close(); 
     } // End Using trans 

    } // End Using connection 

} // End Sub DeleteLargeObject 
+0

Aber das ist keine Antwort auf die Frage (es ist verwandt, aber es ist keine Antwort). –

+0

@Bruno Ranschaert: True - behoben. Aber auch die Antwort mit den meisten Upvotes. Aber die Frage ist nicht "wie man blob/bytea/lobs verwendet", sondern "wie man große Dateien oder Daten in der Datenbank speichert" (wie in der Frage geschrieben) - die Antwort ist: große Dateien gehören nicht in die Datenbank - und ich meine weder als bytea noch als blob. Und meine Antwort beantwortet, wie man das (richtig) macht. Blob ist nicht erforderlich. –

Verwandte Themen