【问题标题】:In what circumstances should you serialize data? When should you not?什么情况下应该序列化数据?什么时候不应该?
【发布时间】:2010-01-09 06:58:47
【问题描述】:

我知道序列化用于 将数据类型转换为可存储 格式,用于缓存等目的。

我更具体地要问的是,您应该在什么情况下实际决定存储数据(在 PHP 中使用 serialize(),在 Python 中使用 pickle 模块等)?

假设我们有一个高流量网站,在我们的/blog 页面中,我们使用静态内容 xml 文件、gettext mo 文件和从数据库动态生成的内容。

示例 #1:

我们依赖的静态内容文件是en/blog.xml

'<content><![CDATA[
<h1>Welcome to my blog!</h1>
<p>Lorem ipsum dolor sit amet..</p>

]]></content>'

我们是否要序列化这个 xml 文件本身并将其存储在缓存中?

示例 #2:

我们还有一个动态生成的表单,通常我会假设我不会序列化任何内容,因为它是服务器端生成的并且是动态的,但是我们的表单字段标签是国际化的,并且用户以西班牙语请求此页面,因此我们使用的是抓取以mo/csv/xml 格式存储的表单字段标签的翻译类。

contact-us.php的内容:

<label for="first_name"><?php echo $L->_("First Name");?></label>
<input id="first_name" name="first_name" type="text">

“名字”消息 id 翻译是从应用程序级翻译文件中提取的,我们对其进行解析并存储在一个数组中,该数组位于我们的翻译类中。所以我们的代码最好不要在每个页面请求上解析mo文件,而是在解析完mo之后序列化整个数组,然后依赖它的序列化转储?

示例 #3:

假设在我们的博客页面上,我们正在提取 5 篇最新的博客文章。

$posts = BlogClass->sql('SELECT blog_message, blog_author FROM blog_posts LIMIT 5 ORDER BY blog_date DESC');

我们是想依赖 memcache 之类的东西,只为 sql 语句的结果设置一个键,它会序列化查询的结果,还是?

奖励:

如果有人能提供有效/实际使用/误用序列化的具体示例,那就太好了 - 就像一个多页、巨大的表单,它可以提取数据库信息并将内容存储在会话中,或者您必须依赖序列化的任何示例..

【问题讨论】:

    标签: php python serialization


    【解决方案1】:

    示例 1

    个人资料。

    • 生成内容页面的成本是否高得令人望而却步?
    • 反序列化生成的内容的成本是否显着降低?

    如果两个答案都是肯定的,请考虑。

    示例 2

    个人资料。

    • 生成内容页面的成本是否高得令人望而却步?
    • 反序列化生成的内容的成本是否显着降低?

    如果两个答案都是肯定的,请考虑。

    示例 3

    个人资料。

    • 该查询是否过于昂贵?
    • 从 memcached 中获取数据是否明显更快?

    如果两个答案都是肯定的,请考虑。

    奖金

    我从不序列化我的数据,因为我可以。我需要有这样做的理由,否则只是过早的优化。有几个因素决定是否应该这样做。

    对序列化的数据集执行排序或其他操作

    这几乎总是一个坏主意。例如如果您从数据库中序列化了一个结果集,然后需要按某个字段重新排序该结果集,那么您就是在自找麻烦。

    消息传递

    如果您需要将序列化数据与其他服务/语言进行通信,那么选择序列化是至关重要的。如果我知道或认为可能需要阅读其他内容,我会避免使用特定于语言的方法进行序列化。 JSON 通常是跨语言序列化的理想格式。

    更新序列化数据

    您必须愿意重新生成序列化数据以更新其源。对序列化数据进行任何类型的复杂更新都会非常昂贵。

    人类可读性

    如果您需要轻松阅读,我建议避免使用特定语言的格式。我建议使用 JSON。

    编辑:

    我刚刚再次查看了示例 3 中的查询。这是一个非常简单的查询,您只选择了 2 个字段,并按日期字段排序。使用正确索引的表,这个查询应该是微不足道的,我不建议将这样的内容缓存到 memcached 中。

    【讨论】:

    • 一般来说反序列化成本较低,对吧?或者这是一个完全愚蠢的问题,因为它总是取决于情况? PS - 很好的答案。
    • @meder:这并不傻。我坚信避免过早优化。您必须衡量差异,看看是否值得。您正在将复杂性引入应用程序,从而增加了混乱(错误)的可能性。
    • +1 我从不序列化我的数据,因为我可以。我这样做需要有一个理由,否则只是过早的优化。
    【解决方案2】:

    您应该在什么情况下实际决定存储数据(在 PHP 中使用 serialize(),在 Python 中使用 pickle 模块等)?

    这个问题很容易回答。各种场景实际上并没有太大的相关性。

    这就是答案您必须在需要时进行序列化。不早了。

    许多 API 不接受 Python 对象。当 API 不能接受 Python 对象时,您通常可以提供一个字符串。那是你序列化的时候。

    示例。您想将 Python 对象保存在持久存储上。可悲的是,file 对象无法编写 Python 对象。所以你序列化。

    示例。您想将 Python 对象发送到另一个进程。您正在使用套接字、命名管道或其他任何东西。这些都是file对象,文件对象不能写成Python对象。所以你序列化。

    那是你序列化的时候。

    1. XML 文件序列化的 DOM 树。 Python 对象是一个 DOM 树。 XML 文件是序列化 DOM 树的一种方式。这个例子我没看懂。

    2. 表单标签字符串是字符串。它们不需要序列化。 I18N 与您的应用程序分开处理。 http://docs.python.org/library/i18n.html这个例子我看不懂。

    3. 这是一个查询。你不序列化任何东西。您只需执行查询。结果(原则上)总是在变化,所以任何序列化都是以前的结果,而不是当前的结果,所以你不要。

    奖金。多页,巨大的表格?你不序列化任何东西。您只需更新 Web 框架中的会话。 Web 框架的会话管理器可能会序列化 Python 对象,但这就是您使用框架的原因——因此您不必关心。

    序列化用于将 Python 对象写入文件。这 - 在 Web 应用程序中 - 很少见。大多数情况下,您使用 SQL 写入数据库。

    【讨论】:

    • 对于#2,我实际上是指序列化解析应用程序级二进制mo 文件(以数组的形式)的结果,而不是文字单个字符串。感谢您花时间回答,这也澄清了一点。
    • @meder: 序列化优化的二进制.mo 文件?太疯狂了。为什么要撤消优化?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多