基本上,我需要将来自多个供应商的产品数据组合到一个数据库中(当然,它比这更复杂),它有几个表需要连接在一起用于大多数OLTP操作.
我将坚持使用默认值并使用自动递增整数作为主键,但是当一个供应商提供他们自己的"ProductiD"字段时,其余的则没有,我将不得不做很多手动映射到另一个表然后加载数据(因为我必须首先将其加载到Products表中,然后将ID拉出并将其与我需要的其他信息一起添加到其他表中).
或者,我可以使用产品的SKU作为主键,因为SKU对于单个产品是唯一的,并且所有供应商都在其数据源中提供SKU.如果我使用SKU作为PK,那么我可以轻松加载数据源,因为所有内容都基于SKU,这就是它在现实世界中的工作方式.但是,SKU是字母数字的,并且可能比基于整数的密钥效率稍低.
我应该关注哪些想法?
这是代理和自然主键之间的选择.
恕我直言总是喜欢代理主键.主键不应该有意义,因为意思可以改变.即使是国名也可以改变,国家可以存在并消失,更不用说产品了.绝对不建议更改主键,这可能发生在自然键上.
有关代理与主键的更多信息:
代理键赢了吧?那么,让我们回顾一下,看看是否有任何自然键的内容适用于代理键:
Con 1:主键大小 - 代理键通常没有索引大小的问题,因为它们通常是int类型的单个列.这个差不多就小了.
第2节:外键大小 - 由于与Con 1相同的原因,它们没有外键或外来索引大小问题.
Con 3:美学 - 嗯,它是beholder类型的东西,但它们当然不涉及编写与复合自然键一样多的代码.
第4和第5节:选择性和适用性 - 代理键对于不想或不能提供数据的人或事物没有问题.
Con 6:独特性 - 100%保证它们是独一无二的.那是一种解脱.
Con 7:隐私 - 如果不道德的人获得隐私,他们就没有隐私问题.
Con 8:意外非规范化 - 您不能意外地非规范化非业务数据.
Con 9:级联更新 - 代理键不会更改,因此不必担心如何在更新时级联它们.
Con 10:Varchar加入速度 - 它们通常是int,因此它们通常可以快速加入.
还有代理键和主键的自然键?
除了最简单的内部情况外,我建议总是选择代理密钥.它为您提供未来的选择,并保护您免受未知因素的影响.
没有理由为什么额外的密钥(如SKU)不能被赋予非空来强制执行它们,但至少通过消除您对第三方的依赖,您可以自行选择,而不是从你,并在以后的阶段经历痛苦的重写.
无论您是使用自动递增的整数还是自己确定下一个主键,都会出现并发症.使用自动递增的方法,您可以轻松插入记录并让它分配自己的密钥,但您可能无法准确识别您的记录的密钥(并且不能保证最大密钥返回您的密钥).
我倾向于使用自我分配的密钥,因为你有更多的控制权,并且在sql server中,你可以从中央密钥表中检索你的密钥,并确保没有其他人获得相同的密钥,所有这些都在一个语句中:
DECLARE @Key INT UPDATE KeyTable WITH (rowlock) SET @Key = LastKey = LastKey + 1 WHERE KeyType = 'Product'
该表记录了最后使用的密钥.上面的sql直接在表中递增该键并返回新键,确保其唯一性.
为什么要避免使用字母数字主键:
三个主要问题:表现,整理和空间.
性能 - 虽然有性能成本,如下面的Razzie,我不能引用任何数字,但索引字母数字而不是数字的效率较低.
排序规则 - 您的开发人员可能会在不同的表中创建相同的键,并且不同的排序规则(它会发生),这会导致在查询中加入这些表时不断使用'collate'命令,并且很快就会变老.
空间 - 像David这样的九个字符的SKU需要9个字节,但是整数只需要4个(smallint为2,tinyint为1).即使bigint只需要8个字节.