现在我的项目需要设计我的数据库 (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
澄清:
状态不是二进制的(表名旁边的“最多 6”)。这些值可能是:
* active
* deleted
* draft
* send
* replaced
我们需要向用户显示解码后的值,所以我们需要名称。
最佳答案
状态表和国家/地区表都非常小,以至于它们在实践中都会驻留在内存中,无论是否正式声明。实际上,除了外键通常需要引用的主键字段上的索引之外,您可能不想理会表上的任何索引。
具有不同类型的连接之间的性能差异将可以忽略不计,并且数字代码(如果有的话)会更慢,因为有“更多”数据要存储(但它太小了,可以忽略不计)。
所以,使用自然代码。除此之外,第一个示例中的 SQL 更清晰; 'UK' 和 'AC' 比 1 和 2 更有意义。
在非 Oracle DBMS 中,您可能会将 CHAR(2) 用于状态和国家/地区代码值。 Oracle 用户倾向于将 VARCHAR2 用于所有事情;我不确定使用 CHAR(2) 列是否会受到惩罚,尤其是因为列值是固定长度的。 (例如,在 Informix 下,一个 VARCHAR(2) 字段 - 一个最多包含两个字符的字段 - 将存储为 3 个字节、一个长度(在您的情况下始终为 2)和 2 个数据字节。相比之下,一个 CHAR(2 ) 字段将仅占用 2 个字节。)
关于performance - Number VS Varchar(2) 主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/324181/