【问题标题】:Would I gain a performance boost by normalizing this table?我会通过规范化此表来提高性能吗?
【发布时间】:2012-08-22 18:35:52
【问题描述】:

我正在我的服务器上运行某种论坛修改代码。在我的数据库中,我有一个名为coreHUGE 表,它基本上包括所有管理员可编辑的设置,其中有很多。我的问题是,我应该标准化吗?

我创建了一个小提琴来告诉你这张桌子有多大:http://sqlfiddle.com/#!2/f4536/1

您会看到一些名为gear_notificationsgear_bankgear_* 等的列。这些列指示某个系统是否已打开。例如,如果gear_bank=1,则银行系统已打开。目前,在我的数据库文件的__construct 中,我运行以下查询:

$settings = mysql_query("SELECT GROUP_CONCAT(d.domain) AS domains, GROUP_CONCAT(d.zb) AS zb_info, c.* FROM core c JOIN domains d ON d.cid = c.id WHERE c.id ='$cid' LIMIT 1");

忽略JOIN,你可以马上看到这里的问题;该查询返回core 表中的每个字段,无论相应的系统是否打开。例如,如果gear_bank=0,查询仍将返回bank_namebank_history_perpagebank_* 等。虽然这不会对代码的运行方式造成任何物理问题(因为它可以忽略它所做的任何数据不需要),如果它不必加载该数据,我会更喜欢。

我最好创建一个名为core 的表,其中包含所有gear_* 值,然后是对应表(core_bankcore_* 等)的对应值?

我一直在查询这个(糟糕的双关语,抱歉!),但我只是不知道这是否会为我的代码提供性能提升。请注意,上述查询将在每个页面上运行。

如果我要恢复到新系统,即多个表,我将如何获得我需要的所有信息?我不想对core 运行一个查询来确定打开了哪些系统,然后在所有相应的表上运行一个额外的查询。我更喜欢基于coregear_* 的值的JOINs 所有必要表的查询。这可能吗?

我还没有发布这个论坛修改,所以我可以在不影响现实世界的情况下进行尽可能多的更改:)

【问题讨论】:

  • 你绝对应该把它标准化。这是一个很好的起点:informit.com/articles/article.aspx?p=30646
  • 如果你把它标准化,你会看到某种性能提升,如果只是因为数据库做的工作更少。
  • 我还建议规范化 - 在任何一种情况下,您都应该优化 sql 以仅返回您想要的行。
  • 好的,谢谢。你能告诉我倒数第二段所说的是否可以实现?
  • 这可能无助于回答您的问题,但您应该停止使用mysql_* 函数。它们正在被弃用。请改用PDO(PHP 5.1 起支持)或mysqli(PHP 4.1 起支持)。如果您不确定使用哪一个,read this article

标签: php mysql join database-normalization


【解决方案1】:

如果您将核心拆分为多个表,则可以使用 NULL 来指示特定条目是否包含特定系统的信息。然后连接将按预期工作。

但是,您的表实际上并没有那么大,而且您是否会真正注意到通过拆分它在应用程序级别上的任何速度改进是值得怀疑的。

如果您不需要查询单个列,那么只需使用一个 TEXT 列,将所有属性放入一个数组中,然后将该数组序列化到文本列中。

【讨论】:

  • 你能给我一个使用JOINNULL 运行的示例查询吗?
  • 一个简单的左连接就可以了。 sql 足够聪明,知道如果您的外键为 NULL,则无需链接到另一个表。
猜你喜欢
  • 2014-06-06
  • 1970-01-01
  • 2021-09-22
  • 2014-08-29
  • 2012-10-08
  • 2010-11-27
  • 2011-02-15
  • 2013-06-13
  • 2021-03-11
相关资源
最近更新 更多