如果我们有一些代码(数据结构)应该存储在数据库中,总有人建议我们存储序列化的数据,而不是原始的代码字符串。在
所以我不太确定为什么我们应该选择序列化数据。在
给出一个简单的实例(在python中):
我们有一个字段可以存储python的dict,比如
{ "name" : "BMW", "category":"car", "cost" : "200000"}
所以我们可以使用pickle(python模块)序列化它,然后将pickle数据存储到db字段。在
或者我们可以直接将dict字符串存储到DB而不需要序列化。在
因为我们需要将字符串转换回python数据,所以两种方法都很容易实现,通过使用酸洗负荷和执行官。在
那么哪一个更适合呢?为什么呢?是因为exec比pickle慢得多吗?或者其他原因?在
谢谢。在
没有所谓的“dict字符串”。有很多方法可以将dict序列化为字符串;您可能认为
repr
,可能是eval
作为获取dict的方法(您提到了exec
,但这很荒谬:您将执行什么语句。。。?!我想你可能是说eval
)。它们的权衡是不同的序列化方法,在许多情况下,权衡往往倾向于pickle(cPickle
,为了速度,协议-1
通常意味着“你能做的最好的”)。在性能当然是一个问题,例如,就存储的大小而言…:
…为什么每次序列化像这样的dict时都要存储1.4kb而不是0.4kb。。。?-)在
编辑:由于有人建议使用Json,因此值得指出的是,Json在这里需要1574个字节——甚至比笨重的repr还要大!在
至于速度。。。在
^{pr2}$…为什么要花10倍的时间?有什么好处可以让你付出如此高昂的代价?在
编辑:json需要2.7毫秒秒——几乎是cPickle的40倍。在
还有一个通用性——并不是每个可序列化的对象都可以正确地使用repr和eval进行往返,而pickle则更为通用。E、 g.:
与
编辑:就往返而言,json甚至不如repr一般。在
因此,比较两种序列化方法(pickling vs repr/eval),我们可以看到:pickling更通用,它可以快10倍,占用数据库空间少3倍。在
您认为repr/eval有哪些补偿优势。。。?在
顺便说一句,我看到一些答案提到了安全性,但这并不是真正的要点:pickling也不安全(eval'untrusted string的安全性问题可能更明显,但是取消对不可信字符串的抓取也是不安全的,尽管是以更微妙和更黑暗的方式)。在
编辑:json更安全。这是否值得在规模、速度和通用性方面付出巨大代价,这是一个值得深思的权衡。在大多数情况下都不会。在
我更喜欢使用JSON之类的标准序列化格式在数据库中存储此类数据。它使数据的使用者可以用python以外的其他语言编写,基本上是人类可读的,而且使用SQL比pickled对象更容易查询。在
存储为字符串和使用pickle都是序列化策略。Pickle的存储方式更灵活,也更紧凑。两种策略,eval(在本例中,您将使用eval而不是exec)和酸洗负荷都是不安全的,这两个都可以运行任意Python代码。在
最好使用JSON(2.6中的JSON模块,simplejson第三方模块pre-2.6版本)之类的序列化格式,这种格式与Python读取无关,如果数据库中存在您不希望的数据,也不会执行任意代码。此外,pickle格式可能会发生变化(而且会丢失数据!),像JSON这样的标准不会以向后不兼容的方式对您进行更改。在
相关问题 更多 >
编程相关推荐