如果有人说只有一种“正确”的方法,你应该对此持怀疑态度。正确的方法取决于情况。使用CPT基础架构有许多显著的好处:
您可以免费获得仪表板UI,您可以自动利用WP的缓存,包括安装可能使用的任何持久缓存插件,您可以自动获得诸如修订后之类的好东西,您可以访问WP_Query
类,这意味着,从理论上讲,如果您计划分发插件或将其开放用于开源开发,则无需编写任何(或至少不太多)可能有缺陷、易受攻击和效率低下的SQL,您可能会发现,开发人员使用自定义post类型和相关的API函数比使用自己的自定义工具更为方便。CPT API的问题主要源于它与“post”的隐喻以及该隐喻附带的数据类型的所有方面高度结合。从MySQL命令行运行DESCRIBE wp_posts
. WP假设您的内容有一个标题,它有一个(单个)作者,您只需要跟踪创建日期和上次编辑日期,您需要空间来放置未索引的post_content
, 等等。这对某些类型的内容很有效,但不一定对其他类型的内容有效。您已经指出了一些潜在问题的方向:
如果我这样做,每个cpt额外字段所需的post元字段的数量,以及这是否会让事情变得“棘手”
有两种方法可以增强wp_posts
通过CPT API的模式:Posteta和分类法。Posteta是未索引的键值对,它非常适合存储大量杂项数据,但对于进行复杂的查找根本没有优化。分类法在这方面更加灵活,但如果您有非常复杂的查找,您仍将面临许多潜在的昂贵子查询。(Themeta_query
和tax_query
不过,参数及其查询构造函数类非常好用。)
如果如您所建议的,您只需要在偶尔报告的情况下执行这些类型的“半复杂关系过滤器”,那么这种架构可能适合您。当您开始向用户公开过滤器时,您必须运行许多复杂的JOIN
s和子查询,事情很快就失控了。
如何最好地管理关系,尤其是如果我有多对多关系
多对多关系是WP-dev社区的长期症结所在(请参阅https://core.trac.wordpress.org/ticket/14513). 通过将分类法项目映射到post\\u id,您可以在不使用自定义表的情况下伪造它(例如,您可以通过说P3有标记“Y-P3”来说“P3有Y到P5的关系”),但这很快就会变得混乱(而且效率很低)。您还可以考虑创建自己的关系表,将CPT链接在一起-您仍然可以获得CPT的好处,并且只创建一个DB表。有关此方法的良好执行版本,请参阅Posts 2 Posts插件:https://wordpress.org/extend/plugins/posts-to-posts/
因此,最终,您应该根据以下内容做出决定:
您将要存储的数据类型-它们的“post”程度如何-所需的查询类型-它们的复杂程度如何-您所需的模式有多复杂,您将拥有多少个总对象,以及您预期的用户数量如果答案是:非常posty,不太复杂,也不必缩放得过大,请使用CPT。否则,请考虑您自己的表。