【问题标题】:Avoid hard coding in mysql query避免在 mysql 查询中进行硬编码
【发布时间】:2013-10-11 15:04:15
【问题描述】:

我有一张封禁原因表:

id | short_name | description
 1      virus     Virus detected in file
 2      spam      Spammy file
 3      illegal   Illegal content

当我禁止某个文件为病毒时,在我的代码中我会这样做:

$file -> banVirus();

将文件id和禁止原因插入到表中:

"INSERT INTO 'banned_files' VALUES (61234, 1)"

我的问题是; 我硬编码了值 1 是否有问题?,表示垃圾邮件文件。

我应该在我的配置中使用定义,如定义('SPAM',1),这样我就可以用定义替换 1 吗?还是根本不重要?

【问题讨论】:

  • 你为什么不把它作为一个可选参数?
  • 如果您维护了代码,您希望在源代码中看到什么,SPAM1
  • 对我来说看起来不错,因为您只有 3 种禁令类型,它们很容易记住。如果你有 50 多个,我可能会有不同的想法。
  • 不是一个真正的问题,但你可能想在评论中说这个1 对应于你的“禁止原因”表中的一个条目,所以以后的维护者知道在哪里看......并且由于您将插入包装在一个具有描述性名称的函数中,这也很有帮助
  • 而不是使用自动递增的主键作为禁止原因 id ...您可以只使用 short_name 保持数据库的关系和规范化,并在其他地方使用时为您提供描述性的禁止原因(例如在应用程序中)。

标签: php mysql oop database-schema


【解决方案1】:

如果id 是一个自动递增 字段,那么这是一个非常大的问题!由于id是自动生成的,稳定性很难保证;即它们可能会改变。

如果id 是您手动分配的,这不是什么大问题,但这是不好的做法。因为幻数很容易导致混乱和错误。谁知道阅读你的代码时“1”是什么意思?

因此,无论哪种方式,您最好为每个案例分配一个稳定、可读的 id。

我同意@Tenner 的观点,从一开始就为这些静态、不变的数据创建一个表也几乎没有意义。你的banned_files 表应该有这样的一列:

reason ENUM('virus', 'spam', 'illegal') NOT NULL

您的数据库中不需要任何其他内容。当为用户输出这个时,你可以通过你的 PHP 代码用一个简单的数组添加一个可读的原因。

【讨论】:

  • 我不同意你的第一句话。虽然它可能是一个自动递增字段,但它位于“查找”表中。还有一个表banned_files,它有一个禁止原因文件的外键。
  • 所以?但是1 在 PHP 中是硬编码的,而数据库中的 id 可能会发生变化。这是一种不稳定的关系,因此是一个问题。
  • 这似乎是一个更好的插入解决方案。如果可能,您能否提供一个简单示例,说明如何使用数组添加可读原因?
  • @paul $reasons = array('virus' => 'The file is a virus.', ...); echo $reasons[$row['reason']];
  • @AgRizzo 无论出于何种原因设置数据库表,而自动增量值未设置为1。记录将收到一些随机 id。您依赖于自动生成的 id 的纯粹事实可能不是每次都以完全相同的方式生成。
【解决方案2】:

由于您有固定(且很少)数量的参数,我很想在您的代码中将 ID 设为枚举,甚至根本不将它们作为单独的数据库表包含在内。

想想性别之类的东西——它有两个(或更多)选项,都是固定的。 (我们不会很快添加多个新性别。)我保证大多数注册系统都没有包含两个条目的 GENDER 表。

所以,banned_files 表应该是这样的:

id      | reason
--------+------------
12345   | 1
67890   | 2

并且您的代码将根据需要包含枚举:

enum BanReason {
    Virus = 1,
    Spam = 2,
    Illegal = 3
}

(请转换为 PHP;我是 C# 开发人员!)

在 PHP 中:

$aBanReason = array(
    'Virus' => 1,
    'Spam' => 2,
    'Illegal' => 3
);

【讨论】:

  • 由于 id 在数据库级别用作列的值,因此在一些带有枚举的随机代码中对其进行描述并不是一个好习惯。它将两者结合在一起,当然不清楚将来是否需要查找它。拥有一个字典表是一种常见的良好做法,除非该值是二进制的,如您提到的 GENDER,其中 MySQL 中的 TINYINT 就足够了,并且列名可以描述自己。
  • 感谢 PHP 的帮助,@CD001!
猜你喜欢
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 2011-01-07
相关资源
最近更新 更多