昨天我正在查看这样的查询:
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/