2010-06-04 2 views
6

2 возможных способа хранения больших строк в хранилище данных Google: Text и Blob типы данных.Google Datastore - Blob или текст

С точки зрения потребления памяти, какой из двух рекомендуется? Тот же вопрос с точки зрения прообраза и десериализации протобуфа.

ответ

4

Не существует существенной разницы в производительности между двумя - используйте только то, что лучше всего подходит для ваших данных. BlobProperty следует использовать для хранения двоичных данных (например, str объектов), в то время как TextProperty следует использовать для хранения любых текстовых данных (например, unicode или str объектов). Обратите внимание: если вы храните str в TextProperty, он должен содержать только байты ASCII (меньше, чем гексагон 80 или десятичный 128) (в отличие от BlobProperty).

Оба эти свойства получены из UnindexedProperty, как вы можете видеть в source.

Вот пример приложения, которое демонстрирует, что нет никакой разницы в накладных для хранения данных ASCII или UTF-8 строк:

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() 

А вот выход:

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

я не был» t известно, что свойства Text могут содержать только ASCII-байты. Это осознание отвечает на мой вопрос. Благодарю. – Keyur

+1

Это не так - текстовые свойства сохраняют unicode. Но если вы присвоите строковое значение байта ('raw') (type 'str') для свойства text, оно попытается применить к unicode, который использует кодировку по умолчанию, которая является ASCII. Вы должны явно декодировать строки, если хотите сделать иначе. –

+0

Спасибо, Ник. Я пытался сказать, что 'TextProperty' не может хранить объекты' str', которые содержат байты без ASCII, но (как вы указали) мой комментарий не сделал этого ясно, поэтому я удалил его. –

Смежные вопросы