11

我现在到了我需要设计我的数据库(Oracle)的项目的这一点。通常对于状态和国家表,我不使用数字主键,例如

STATUS (max 6)
AC --> Active
DE --> Deleted

COUNTRIES (total 30)
UK --> United Kingdom
IT --> Italy
GR --> Greece

这些表是静态的,不会通过应用程序更新,并且预计将来不会更改,因此在将这些值用作外键的表中不会出现更新问题。

应用程序的主表将使用状态和国家(不止一次,例如来源国、目的地国),预计每年将增加 600000 行

所以我的问题是,在查询 3 个表的连接时,这些 VARCHAR(2) 键是否会对性能产生影响。第一个会比第二个慢很多吗?

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 'AC'
   AND m.country_cd = 'UK'

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 1
   AND m.country_cd = 2

澄清:

状态不是二进制的(表名旁边的“max 6”)。这些值可能是:

* active
* deleted
* draft
* send
* replaced

我们需要向用户显示解码后的值,所以我们需要名称。

4

4 回答 4

5

状态表和国家表都非常小,以至于无论是否正式声明,它们都将成为实践中的常驻内存。实际上,除了外键通常需要在所引用的主键字段上建立索引外,您可能不想打扰表上的任何索引。

不同类型的连接之间的性能差异将可以忽略不计,如果有的话,数字代码会变慢,因为要存储“更多”数据(但它是如此之小以至于可以忽略不计)。

因此,请使用自然代码。除此之外,第一个示例中的 SQL 更清晰;'UK' 和 'AC' 比 1 和 2 更有意义。

在非 Oracle DBMS 中,您可能会将 CHAR(2) 用于状态和国家代码值。Oracle 用户倾向于使用 VARCHAR2 来处理所有事情;我不确定使用 CHAR(2) 列是否会受到惩罚,特别是因为列值是固定长度的。(例如,在 Informix 下,一个 VARCHAR(2) 字段 - 最多两个字符的字段 - 将存储为 3 个字节、一个长度(在您的情况下始终为 2)和 2 个数据字节。相比之下,一个 CHAR(2 ) 字段将只占用 2 个字节。)

于 2008-11-27T17:20:17.923 回答
2

看看这个链接。底线是 varchar 和 num 之间没有太大的性能差异。因此,您应该选择对专栏有意义的内容。在这里,varchar 似乎更有意义。

于 2008-11-27T17:08:16.623 回答
0

如果“状态”是(并且将永远是?)二进制活动/已删除字段,为什么还要打扰表格。这似乎是标准化到了一个不切实际的极端。

简单地使用 tinyint(1) 字段并将活动/删除状态记录为 1 或 0肯定更快,更不用说更容易了。

这完全消除了你的一个连接,这一定是件好事。

于 2008-11-27T16:36:43.083 回答
0

在这种情况下,您选择哪种方法并不重要。重要的部分是在整个数据库中使用相同的类型,并且在您的 id 约定中保持一致。

于 2008-11-27T17:17:30.380 回答