数据库设计 - 使用Short而不是Varchar - 用于状态字段

时间:2012-08-11 13:29:27

标签: java database database-design database-performance

以下方法可用于在DB表中设计与状态相关的字段。

方法01:

  • 使用'VARCHAR'作为数据类型。
  • 直接状态将存储为NEW,IN PROGRESS,CLOSED

限制:

  • 在表格中搜索字符串总是需要更多的时间和时间。资源
  • 更改现有状态文本(例如:'关闭'为'已完成')需要完整的表格更新

方法02:

  • 创建状态查找表
  • 将状态表用作从属表中的外键

限制:

  • 维护外键关系
  • 需要对应用程序中的所有相关查询使用JOIN

方法03:

  • 对状态字段使用short(或)int
  • 使用应用程序界面(EJB)中的ENUM维护状态文本

这将解决以前方法的局限性

限制:

  • 需要将整数映射到相关状态(但仍然使用枚举而不是文本是更好的方法)

我觉得第三种方法在提高效率方面会更有效率 *更快的数据库索引 *由于短(或)int字段(而不是)varchar而导致搜索速度更快 *当然少记忆指纹

请问在第三种方法的灵活性,维护和性能方面是否存在任何陷阱?

提前致谢

3 个答案:

答案 0 :(得分:2)

在我们的应用程序中,我们使用了

  [enum,VARCHAR(30)]

PROCESS TYPES

  [String,VARCHAR(1)]

PROCESS STATUS

enum看起来是一个更好的选择,因为它可以在Java代码中保存String比较。 所以我相信如果你选择实现为[enum,NUMERIC]字段,它应该一直都是......

答案 1 :(得分:2)

Approach 02 :

Create a status look-up table
Use the status table as a foreign key in the dependent tables
Limitations :

Maintaining the foreign key relationships
Need to use JOIN for all the related queries in application

如果作为查找表的外键存储的值不是人类可读的,或者仅适用于全文,则只需使用连接。如果使用整数,则始终需要连接。但是你可以为一些表使用人类可读的代码。查询char(1)可能比整数更快。 (如果你只有三个不同的值和1亿行,这些都不会很快。)

    status_code   status
    --
    N             New
    P             In progress
    C             Closed

将“已关闭”更改为“已完成”只需更新一行,但我认为这是巧合。

Approach 03 :

Use short (or) int for the status field
Maintain the status text using ENUM in the application interfaces(EJB)

我讨厌必须维护一个只有整数值的数据库。

如果您要在此处存储整数,则该整数必须是存储实际感兴趣的值的表的外键。您的应用程序ENUM也应该通过查询该表来生成。

答案 2 :(得分:1)

在我们的项目中,我们使用了与您的#3非常相似的方法。在Java方面,我们使用了enum s。我们使用JPA的@Enumerated(EnumType。Ordinal)在持久化到数据库时将枚举映射到数字。我们将状态文本嵌入到枚举中(参见下面的示例),但它也可以完全分开。

<强>优点:

  • 与使用数字或字符串相比,Java代码更不容易出错。
  • 数据库部分它的空间和CPU使用效率都很高。
  • 您可以随意重命名enum项目(但不能重命名或移动,请参阅缺点部分)。

<强>缺点:

  • 数据库中的数字是枚举的ordinal numbers。因此,您无法删除或重新排序Java代码中的enum项。您只能在列表末尾添加新的。这取决于你的情况,但对我们来说这并不是什么大不了的事。没有理由移动枚举项的顺序。如果我们想删除一个项目,我们只需将其重命名为REMOVED_STATUS_XY,以确保代码中不再使用它。

public enum Status {
    EXAMPLE_STATUS("User status message"),
    ... ;

    private Status(String label) {
        this.label = label;
    }
    private final String label;

    public final String label() {
        return label;
    }
}