![]() |
1
9
数据库规范化螺母将告诉您一件事。 我只想对这些年来我学到的东西发表我自己的看法。我在我的每一张表上都添加了一个自动递增的ID字段。从长远来看,它使生活变得容易上百万倍,能够在不受惩罚的情况下,一排一排地单独出去。 这是来自一个“战壕深处”的开发者。 |
![]() |
2
3
单列键易于编写、维护和理解。 如果你要有大量的行-数十亿?-也许在这里保存一个字节会有所帮助。 但是,如果您不关注极端情况,优化“简单”通常是最好的方法。 |
![]() |
3
3
如果您是一个编码人员,而数据库对您来说只是一个美化的对象存储区,那么当然,无论如何都会随意地注入代理键。事实上,做得更好,只需将所有的DB模式设计和DB交互委托给您最喜欢的ORM,并完成它。事实上,当我想要一个中小型的对象存储时,这正是我要做的。 如果您正在接近一个信息系统或信息管理问题,那么这是一个完全不同的情况。当你开始处理10年代(或者更可能是100年代)数以百万计的来自多个来源的肮脏记录时,其中的一些或全部不在你的控制之下;这时,一个简单的“身份”问题答案的诱人诱惑是一个陷阱。 是的,您有时仍然会在内部引入代理键,以便在覆盖索引上实现简洁的FK关系和提高缓存效率;但是,您获得这些好处的代价是在管理自然键/代理键关系时付出了巨大的代价。 在这种情况下,确保不允许代理密钥泄漏是很重要的。业务逻辑层的公共API应该使用自然键,文档/记录缓存之上的任何内容都不应该知道代理键的存在。请注意,与现有的代理键匹配更新的成本可能是令人望而却步的,而且与通过内部网络在每个请求上移动几个额外字节的增量成本相比,它的可伸缩性受到的影响要大得多。 综上所述:
更新 代理密钥的“便利性”实际上只是在身份问题上的一种能力。这在数据库中经常是必要的,在我允许的缓存层中也是合理的,但除此之外,它会导致脆弱的数据设计。问题是,身份不是一个有身份的东西 对的 回答。对于非琐碎的数据密集型系统,您通常会发现自己需要在以下方面工作: 等价类 而不是参考标识,面向对象编程让我们陷入思考是 正常的 . 它真正的归根结底是认识到,“主键”的整个概念是为了帮助关系模型高效工作而发明的一个虚构的概念;但是,采用一个替代键,巩固了这种虚构,并使整个系统变得脆弱和不灵活。业务逻辑需要能够提供自己的平等定义,有时四份相同的定义。 文件 需要考虑四个 文件夹 有时,它们应该被认为与原始的不可区分。 文件 ;当您编辑其中一个时,这是一个新的 文件 ?相同的 文件 ?两个问题的答案当然是 是的,什么时候… 使用自然键提供了在概念等价类方面工作的关键能力。如果您让代理键影响您的业务逻辑,您很快就会失去它。 |
![]() |
4
2
过去我不得不使用多列主键,很快就变成了一场噩梦。 如果有一个表引用了第一个表,那么它如何包含该主键?现在添加另一个只引用第二个表但需要在第一个表中查找数据的表。现在另一个…在兔子洞下面。 如果您知道只有一个表,那么任何一种方法都可能没有问题——使用更好的表来表示您的数据。但是,如果您将在联接中使用它,您可能会很快失去性能。 |
![]() |
5
2
对。如果主键恰好也是聚集索引,则通常会为表中的每个辅助索引完全复制聚集索引。因此,拥有一个更胖的聚集索引(这是使用复合索引可以得到的)意味着存储成本的增加。此外,国外提到 这 表将需要指定这两个字段以引用唯一条目,这意味着进一步的存储成本。由于连接的复杂性略有增加,因此开发时间的成本可能会更高。 另一方面,根据两个关键字段值的分布情况,可能是因为在不同的物理页上可能会发生按时间顺序连续插入,所以对表的并发访问得到了很大的改善;例如,如果字段是独立于时间的(并且非单调的,如增加)比如 cliclid 或者类似的。这对于高并发环境中的性能可能非常重要。
如果查询表的最常见方法是将这三个字段指定为限制,那么将这三个字段都包含在复合键中可能是最快的查找。 还有一点我几乎忘记了。因为具有复合键意味着外部引用 这 来自其他表的表必须指定键中的所有字段,这也意味着对 其他 需要对复合索引的一个或多个部分进行限制的表 这 表,可以执行 无需加入 . 这可以被认为类似于为了性能而非规范化的概念(并且可以说牺牲了一点易维护性)。 |
![]() |
6
1
一般来说,我更喜欢使用代理密钥,因为真正好的自然密钥很少(密钥问题不是唯一性,而是随时间变化),而且自然密钥越长,用作pk时对性能的影响就越大。如果您有一个自然键,您应该在它上面创建一个唯一的索引,然后使用代理键作为用于连接到其他表的pk。这加强了自然键数据的唯一性,但解决了连接性能的问题,以及在自然键更改时更新所有子记录的额外时间。 有一种情况我忽略了这一点,那就是一个联接表。如果它是一个用于强制多对多关系的表,并且只包含来自其他表的两个代理键,那么添加代理键实际上不会获得任何好处。通常,单个键用于联接,而不是pk和代理键几乎从不更改。在一个连接表中,我只添加我需要的两个列,而不添加其他列。 |
![]() |
7
0
在我认识的大多数数据库(mysql,postgresql)中,复合键将生成一个索引。因此,如果您将键指定为复合键,那么db应该为您提供一种使用该键从db中查找元组的有效方法。我认为这是所有星展银行的情况。我想你不必为那里的表演操心。 |
![]() |
8
0
不要使用多列键。它们变得很难维护,尤其是当钥匙的组件不为人类所理解时。 而是使用内部生成的密钥。 |
![]() |
9
0
假设您有一个复合主键(例如field1和field2),而不是一个自动增量标识符。客户机的需求是非常多变的,在一些开发之后,客户机说field2不是强制的,它可以为空,不能继续作为表的主键。假设此表是模型中最重要的表之一。如果字段2不能在复合主键中,则应更改所有外键。在整个模型中更改主键是一个噩梦。 另外,如果有很多外键,我认为在每个表中添加几个键只是为了建立链接不是一个好主意。 |
![]() |
10
0
我不确定是否有足够的信息让我们帮你打电话。以下是一些可能有用的观察结果。 主键是聚集索引吗?该表是否由其他表通过外键引用?如果是,那么您可能会受益于单列键,因为该键将出现在其他表中。这就是节省空间的方法。 如果表没有被其他表引用,那么您将在表中使用额外的空间,而不会有太多额外的好处。而且,如果这个表现在只包含这两列,那么您将把表的大小增加50%。 如果对主键使用额外的列,请不要忘记您的自然键(两列键)。在复合键上创建唯一约束。您仍然希望维护真实数据的完整性。 |
![]() |
11
0
决策应始终基于需求和数据的预期含义。只有一个属性键的表显然会强制执行不同类型的约束,这意味着您的表对具有多属性键的同一个表具有非常不同的含义。另一方面,如果您实际上不需要在任何地方使用它,那么添加一个额外的惟一列也会浪费资源,增加毫无意义的复杂性。 |
![]() |
12
0
对自动递增列的一个警告是,它可能会给人一个错误的唯一性印象。当然,您的标识列总是唯一的,但这只是您附加到表中的一个毫无意义的值。除非在表示表的实际语义主键的列集上附加了唯一约束,否则无法保证有意义的唯一性。 |
![]() |
Michael Samuel · MYSQL在以下情况下自动创建索引 6 年前 |
![]() |
Patricia Rozario · 数据库设计确保一对一关系 7 年前 |
![]() |
dryhay · MySQL“多对多”关系错误 7 年前 |
![]() |
L. Fox · 我在这里用的是什么样的Laravel雄辩的关系 7 年前 |
![]() |
Geoff Harper · 我应该如何构建关系松散的SQL db 7 年前 |
![]() |
waroxx · SQL—当多个表具有相同的列时,最好怎么做 7 年前 |
![]() |
Lumpi01 · SQL 2不同的注释类型-最佳解决方案? 7 年前 |
![]() |
Hayreddin Tüzel · 预约系统数据库建模[关闭] 7 年前 |