2010-06-04 9 views
6

2 możliwymi sposobami utrwalania dużych ciągów w Google Datastore są typy danych Text i Blob.Google Datastore - Blob lub tekst

Z punktu widzenia zużycia pamięci, który z 2 jest zalecany? To samo pytanie z perspektywy serializacji prototypów i deserializacji.

Odpowiedz

4

Nie ma znaczącej różnicy w wydajności między tymi dwoma - wystarczy użyć tego, który najlepiej pasuje do danych. BlobProperty należy używać do przechowywania danych binarnych (np. Obiektów str), a do przechowywania jakichkolwiek danych tekstowych (np. Obiektów unicode lub str) należy użyć kodu TextProperty. Zauważ, że jeśli przechowujesz str w TextProperty, musi zawierać tylko bajty ASCII (mniej niż 80 lub 128) (w przeciwieństwie do BlobProperty).

Obie te właściwości pochodzą z UnindexedProperty, jak widać w source.

Tutaj jest app próbki, które pokazuje, że nie ma różnicy w obciążeniu pamięci dla tych ASCII lub UTF-8 ciągi:

import struct 

from google.appengine.ext import db, webapp 
from google.appengine.ext.webapp.util import run_wsgi_app 

class TestB(db.Model): 
    v = db.BlobProperty(required=False) 

class TestT(db.Model): 
    v = db.TextProperty(required=False) 

class MainPage(webapp.RequestHandler): 
    def get(self): 
     self.response.headers['Content-Type'] = 'text/plain' 

     # try simple ASCII data and a bytestring with non-ASCII bytes 
     ascii_str = ''.join([struct.pack('>B', i) for i in xrange(128)]) 
     arbitrary_str = ''.join([struct.pack('>2B', 0xC2, 0x80+i) for i in xrange(64)]) 
     u = unicode(arbitrary_str, 'utf-8') 

     t = [TestT(v=ascii_str), TestT(v=ascii_str*1000), TestT(v=u*1000)] 
     b = [TestB(v=ascii_str), TestB(v=ascii_str*1000), TestB(v=arbitrary_str*1000)] 

     # demonstrate error cases 
     try: 
      err = TestT(v=arbitrary_str) 
      assert False, "should have caused an error: can't store non-ascii bytes in a Text" 
     except UnicodeDecodeError: 
      pass 
     try: 
      err = TestB(v=u) 
      assert False, "should have caused an error: can't store unicode in a Blob" 
     except db.BadValueError: 
      pass 

     # determine the serialized size of each model (note: no keys assigned) 
     fEncodedSz = lambda o : len(db.model_to_protobuf(o).Encode()) 
     sz_t = tuple([fEncodedSz(x) for x in t]) 
     sz_b = tuple([fEncodedSz(x) for x in b]) 

     # output the results 
     self.response.out.write("text: 1=>%dB 2=>%dB 3=>%dB\n" % sz_t) 
     self.response.out.write("blob: 1=>%dB 2=>%dB 3=>%dB\n" % sz_b) 

application = webapp.WSGIApplication([('/', MainPage)]) 
def main(): run_wsgi_app(application) 
if __name__ == '__main__': main() 

I tu jest wyjście:

text: 1=>172B 2=>128047B 3=>128047B 
blob: 1=>172B 2=>128047B 3=>128047B 
+2

Nie byłem” t świadomy, że właściwości tekstu mogą zawierać tylko bajty ASCII. Ta realizacja odpowiada na moje pytanie. Dzięki. – Keyur

+1

To nie jest prawda - właściwości tekstu przechowują kod Unicode. Ale jeśli przypiszesz ciąg bajtowy ("raw") (typ "str") do właściwości text, spróbuje on przesłać do Unicode, który używa domyślnego kodowania systemowego, czyli ASCII. Jeśli chcesz inaczej, musisz jawnie dekodować ciągi. –

+0

Dzięki Nick. Próbowałem powiedzieć, że 'TextProperty' nie może przechowywać obiektów' str', które zawierają bajty inne niż ASCII, ale (jak zauważyłeś) mój komentarz nie wyjaśnił tak, więc usunąłem go. –

Powiązane problemy