Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 数字VS Varchar(2)主键_Performance_Primary Key_Numbers_Varchar - Fatal编程技术网

Performance 数字VS Varchar(2)主键

Performance 数字VS Varchar(2)主键,performance,primary-key,numbers,varchar,Performance,Primary Key,Numbers,Varchar,我现在已经到了我的项目的这一点,我需要设计我的数据库(Oracle)。 例如,对于status和countries表,我通常不使用数字主键 STATUS (max 6) AC --> Active DE --> Deleted COUNTRIES (total 30) UK --> United Kingdom IT --> Italy GR --> Greece 这些表是静态的,不会通过应用程序进行更新,并且预计将来不会发生更改,因此在将这些值用作外键的表中不

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

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
我们需要向用户显示解码后的值,因此我们需要名称。

如果“状态”是(并且将始终是?)二进制活动/删除字段,那么为什么还要处理表呢。看来正常化已经走到了不切实际的极端

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


这将完全消除一个连接,这肯定是一件好事。

请查看此链接。底线是varchar和num之间没有太大的性能差异。所以您应该选择对该列有意义的。在这里,varchar似乎更有意义。

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

状态表和国家/地区表都非常小,实际上它们将是内存驻留表,无论是否正式声明。实际上,除了外键通常需要引用的主键字段上的索引外,您可能不想麻烦处理表上的任何索引

不同类型的联接之间的性能差异可以忽略不计,数字代码的速度也会变慢,因为要存储的数据“更多”(但数据太小了,可以忽略不计)

所以,遵循自然法则。除此之外,第一个示例中的SQL更清晰;“UK”和“AC”比1和2更有意义


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

因为问题说有6个状态码,它不是二进制字段。您在Oracle中使用的是VARCHAR2还是VARCHAR(2)? 如果使用Oracle VARCHAR2,则括号具有误导性。如果是VARCHAR(2),那么为什么不是CHAR(2)呢?通常效率更高。在Oracle中,CHAR和VARCHAR字段完全相同地存储在磁盘上,只是CHAR字段被强制填充到指定的长度。