Sql 性能-整型vs字符(3)

Sql 性能-整型vs字符(3),sql,sql-server,performance,primary-key,Sql,Sql Server,Performance,Primary Key,我有一张桌子,正在讨论两种不同的信息存储方式。它的结构是这样的 整数id int FK_id varchar(50)info1 varchar(50)info2 varchar(50)info3 int-forTable或char(3)forTable FK_id可以是6个表之一的外键,因此我需要另一个字段来确定它用于哪个表 我看到两种解决办法: 具有实际值的设置表的FK整数 带有表的缩写版本的字符(3)字段 我想知道是否有人知道一个比另一个在速度方面更有利,或者使用char(3)是否会有任

我有一张桌子,正在讨论两种不同的信息存储方式。它的结构是这样的

整数id

int FK_id

varchar(50)info1

varchar(50)info2

varchar(50)info3

int-forTable或char(3)forTable

FK_id可以是6个表之一的外键,因此我需要另一个字段来确定它用于哪个表

我看到两种解决办法:

  • 具有实际值的设置表的FK整数
  • 带有表的缩写版本的字符(3)字段
我想知道是否有人知道一个比另一个在速度方面更有利,或者使用char(3)是否会有任何重大问题


注意:我将为此字段的6个不同值中的每一个创建索引视图。此表将包含约30k行,需要与更大的表连接

您是否考虑过使用TinyInt。只需要一个字节来存储它的值。TinyInt的值范围在0到255之间。

我认为这里需要一个小整数(TinyInt)。“缩写版本”看起来太像一个神奇的数字了


我还认为在性能方面,整数应该优于字符(3)。

在这种情况下,除了排序开销(
A
vs
A
vs
A
va
A

我会使用char(3),比如说CHF、GBP等货币代码,但如果我的自然键是“瑞士法郎”、“英镑”等,我会使用数字


3字节+排序规则vs 4字节数字?在这件事变得重要之前,你需要数不清的行数或运行一个中等规模的国家…

首先,一个50个字符的Id不是全球唯一的,听起来有点吓人。ID有什么意义吗?如果没有,您可以在更少的空间中轻松获得GUID。就我个人而言,只要有可能,我都是一个让人可读的人。我会,而且已经,把全名放在图表中,直到我需要做其他事情。不过,我更喜欢为每个可能的相关表设置链接表

除非您谈论的是真正的大规模,否则最好减小ID的大小,并为表的名称增加几个字符。对于非常大的规模,我会减小ID的大小并使用整数


雅各伯

< P>因为数据库约束无法执行FK(因为它是依赖于类型的变体),所以我强烈考虑重新评估你的设计使用链接表,其中每个链接表包括两个FK列,一个是实体的PK,一个是6个表中的一个PK。 虽然这似乎有些过分,但它使很多事情变得更简单,添加新的链接表并不比适应新的FK类型更复杂。此外,它更容易扩展到实体需要与单个表的1-1关系以上,或需要与其他6个实体的多个1-1关系的情况

在不同的FK场景中,可能会丢失数据库一致性,可能会由于忽略对类型代码进行筛选而加入错误的实体,等等


我应该补充一点,链接表的另一个巨大好处是,您可以链接到具有不同数据类型的键(int、自然键等)的表不必添加surrograte键,也不必将键存储在varchar或类似的解决方案中,这样容易出现问题。

是您需要一个表的原因,您希望确保当六个父表引用子行的给定实例时,该子行的给定实例保证为同一实例?这是典型的“多亲”问题。例如,您可能会遇到多人/联系人表中的地址或电话号码

我可以想出几个选择:

选项1:每个父表的链接表。这就是霍伊尔建筑。比如说:

Create Table MyTable(
                    id int not null Primary Key Clustered
                    , info1 varchar(50) null
                    , info2 varchar(50) null
                    , info3 varchar(50) null
                    )

Create Table LinkTable1(
                        MyTableId int not null
                        , ParentTable1Id int not null
                        , Constraint PK_LinkTable1 Primary Key Clustered( MyTableId, ParentTable1Id )
                        , Constraint FK_LinkTable1_ParentTable1
                            Foreign Key ( MyTableId )
                            References MyTable ( Id )   
                        , Constraint FK_LinkTable1_ParentTable1
                            Foreign Key ( ParentTable1Id )
                            References ParentTable1 ( Id )  
                        )
...
Create Table LinkTable2...LinkTable3
选择2。如果您知道您永远不会拥有超过六个表,并且愿意接受一些非规范化和fugly设计,那么您可以向主表添加六个外键。这避免了填充一堆链接表的问题,并确保了适当的引用完整性。然而,如果父母数量增加,这种设计很快就会失控

如果您对现有的设计感到满意,那么关于字段大小,我将使用完整的表名。坦率地说,char(3)和varchar(50)甚至varchar(128)之间的性能差异对于您可能放入表中的数据量来说可以忽略不计。如果你真的认为你将有数以百万计的行,那么我会强烈地考虑链接表的选项。
如果您希望继续使用您的设计并获得最大的性能,那么我将使用一个带有外键的tinyint来访问一个表,该表包含带有tinyint主键的六个表的列表。这样可以防止数字变“魔术”,并确保缩小父表列表的范围。当然,它仍然不能阻止孤立记录。在这种设计中,您必须使用触发器来完成此操作。

表定义的第一行是什么意思?int-id-int-FK_-id-varchar(50),那么FK值可以是其他6个表中1个表的主键?@KM,这意味着编辑器得到了我。现在修好了@我知道功夫是正确的。这是因为每个表中都有相同的信息,但我需要能够访问其中的任何一个,而不必合并6个表中的每一个。好的,我现在明白了。但是,前两个是datatype-column,其余的是column-data-type;-)对不起,编辑雅各布(或我)在写这篇文章时有点搞混了。PK是一个整数自动递增字段。varchar50不应该在那条线上。不知怎的,它放错了位置,我在快速阅读时错过了。明白了。32位与100字节之间有点不同。我想说,从速度的角度来看,整数比较是一个单CPU指令