sql - 使用 JOIN 来避免数字 ID 是一件坏事吗?

标签 sql oracle join

昨天我正在查看这样的查询:

SELECT <some fields>
FROM Thing
WHERE thing_type_id = 4

...并且不得不认为这非常“可读”。 ‘4’是什么?这是什么意思?我之前在编码语言中做了同样的事情,但现在我会使用常量来实现这一点,将 4 变成 THING_TYPE_AVAILABLE 或类似的名称。不再有任何意义的神秘数字!

I asked about this on here并得到了如何在 SQL 中实现这一目标的答案。

我主要偏向于将 JOINS 与现有类型表一起使用,其中您有 ID 和代码,当没有此类表时可能会使用其他解决方案(并非每个数据库都是完美的......)

SELECT thing_id
FROM Thing
JOIN ThingType USING (thing_type_id)
WHERE thing_type_code IN ('OPENED', 'ONHOLD')

所以我开始在一两个查询中使用它,我的同事很快就发现了我:“嘿,你的查询中有文字代码!” “嗯,你知道,我们通常会为此进行PK”。

虽然我可以理解这个方法不是通常的方法(嘿,直到现在也不适合我),但它真的有那么糟糕吗?

这样做的优点和缺点是什么?我的主要目标是可读性,但我担心性能,想确认这个想法是否合理。

编辑:请注意,我不是在谈论 PL/SQL,而是直接查询,通常以 SELECT 开头的那种。

编辑2: 为了通过虚假(但结构相似)的示例进一步阐明我的情况,这里是我的表格:

Thing
------------------------------------------
thing_id | <attributes...> | thing_type_id
    1                              3
    4                              7
    5                              3

ThingType
--------------------------------------------------
thing_type_id | thing_type_code | <attributes...>
       3           'TYPE_C'         
       5           'TYPE_E'
       7           'TYPE_G'

thing_type_code 与 thing_type_id 一样唯一。它目前也用作显示字符串,在我看来这是一个错误,但通过添加一个复制 thing_type_code 的 thing_type_label 字段可以很容易地修复,并且如果需要的话可以在以后随时更改。

据说,使用 thing_type_code = 'TYPE_C' 进行过滤,我肯定会得到恰好是 thing_type_id = 3 的一行。连接仍然可以(而且很可能应该)使用数字 ID 来完成。

最佳答案

主键值不应在查询中编码为文字。

原因是:

  • 关系理论认为 PK 不应传达任何含义。连具体的身份都没有。它们应该是严格的行标识符,而不是依赖于特定值
  • 由于操作原因,不同环境(如开发、质量保证和生产)中的 PK 通常会有所不同,即使对于“查找”表也是如此

由于这些原因,在查询中编码文字 ID 很脆弱。

对诸如'OPENED''ONHOLD'之类的数据文字进行编码是一种很好的做法,因为这些值在所有服务器和环境中都将保持一致。如果它们确实发生更改,则将查询更改为同步将成为更改脚本的一部分。

关于sql - 使用 JOIN 来避免数字 ID 是一件坏事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21908335/

相关文章:

mysql - 为什么mysql转义会破坏整个查询?

sql - 从Oracle数据库获取所有建表脚本

java - 通过 java 将日期列表传递给 oracle db 函数

mysql - 将Oracle查询转换为与xmldatatype相关的mysql

mysql - 将多个列内连接到一个 ID

c++ - 多台机器运行相同的软件,有些无法连接到 firebird

sql - ORACLE SQL listagg函数

sql - 我需要有关 SQL 查询的帮助。获取一个条目,它是最新的修订版和它的字段

MySQL 加入更新

sql - 使用大量不同的需要知道的信息来建模产品并将它们链接到订单项?