简体   繁体   English

MySQL-自动增量+复合主键-性能和完整性

[英]MySQL - autoincrement + compound primary key - performance & integrity

I have a database design that makes use of compound primary keys to ensure uniqueness and which are also foreign keys. 我有一个数据库设计,该数据库使用复合主键来确保唯一性,并且这也是外键。

These tables are then linked to other tables in the same way, so that in the end the compound key can get up to 4 or 5 columns. 然后将这些表以相同的方式链接到其他表,以便最终复合键最多可以包含4或5列。 This led to some rather large JOINs, so I thought a simple solution would be to use an autoincrement column which is not part of the primary key but which is used as part of the primary key of other table(s). 这导致了一些相当大的JOIN,因此我认为一个简单的解决方案是使用一个autoincrement列,该列不是主键的一部分,而是用作其他表的主键的一部分。

Here is some pseudo code showing the general layout : 这是一些显示一般布局的伪代码:

CREATE TABLE Item (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
) ENGINE = InnoDB;

CREATE TABLE PriceCategory (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
)

CREATE TABLE ItemPriceCategory (
itemId,
priceCategoryId,
id AUTO_INCREMENT,
...
UNIQUE INDEX id,
PRIMARY KEY (eventId, priceCategoryId)
)

CREATE TABLE ClientType (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
)

CREATE TABLE Price (
itemPriceCategoryId,
clientTypeId,
id AUTO_INCREMENT,
...
UNIQUE INDEX id,
PRIMARY KEY (itemPriceCategoryId, clientTypeId)
)

table Purchase (
priceId,
userId,
amount,
PRIMARY KEY (priceId, userId)
)

The names of tables have been changed to protect the innocent ;-) Also the actual layout is a little deeper in terms of references. 表的名称已更改,以保护纯真;-)实际的布局在引用方面也更深一些。

So, my question is, is this a viable strategy, from a performance and data integrity point of view ? 因此,我的问题是,从性能和数据完整性的角度来看,这是否可行? Is it better to have all keys from all the referenced tables in the Purchase table ? 将所有引用的表中的所有键都包含在Purchase表中是否更好?

Thanks in advance. 提前致谢。

Generally, the advice on primary keys is to have "meaningless", immutable primary keys with a single column. 通常,关于主键的建议是将“无意义”的,不变的主键放在同一列中。 Auto incrementing integers are nice. 自动递增整数很好。

So, I would reverse your design - your join tables should also have meaningless primary keys. 因此,我将撤销您的设计-您的联接表也应具有无意义的主键。 For instance: 例如:

CREATE TABLE ItemPriceCategory (
itemId,
priceCategoryId,
id AUTO_INCREMENT,
...
PRIMARY KEY id,
UNIQUE INDEX  (eventId, priceCategoryId)
)

That way, the itemPriceCategoryId column in price is a proper foreign key, linking to the primary key of the ItemPriceCategory table. 这样,price中的itemPriceCategoryId列是正确的外键,链接到ItemPriceCategory表的主键。

You can then use http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html foreign keys to ensure the consistency of your database. 然后,您可以使用http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html外键来确保数据库的一致性。

In terms of performance, broadly speaking, this strategy should be faster than querying compound keys in a join, but with a well-indexed database, you may not actually notice the difference... 从性能上来说,从广义上讲,此策略应该比查询联接中的复合键更快,但是对于索引良好的数据库,您实际上可能不会注意到其中的区别。

I think that something has been lost in translation over here, but I did my best to make an ER diagram of this. 我认为在这里的翻译中有些东西丢失了,但是我尽了最大的努力对此做了一个ER图。

In general, there are two approaches. 通常,有两种方法。 The first one is to propagate keys and the second one is to have an auto-increment integer as a PK for each table. 第一个是传播密钥,第二个是为每个表使用一个自动递增的整数作为PK

The second approach is often driven by ORM tools which use a DB as object-persistence storage, while the first one (using key propagation) is more common for hand-crafted DB design. 第二种方法通常由ORM工具驱动,后者使用DB作为对象持久性存储,而第一种方法(使用密钥传播)在手工设计的DB设计中更为常见。

In general, the model with key propagation offers better performance for "random queries", mostly because you can "skip tables" in joins. 通常,具有键传播的模型可为“随机查询”提供更好的性能,这主要是因为您可以在联接中“跳过表”。 For example, in the model with key propagation you can join the Purchase table directly to the Item table to report purchases by ItemName . 例如,在具有密钥传播的模型中,您可以将Purchase表直接连接到Item表,以按ItemName报告购买。 In the other model you would have to join Price and ItemPriceCategory tables too -- just to get to the ItemID . 在另一个模型中,您也必须加入PriceItemPriceCategory表-只是要获得ItemID

Basically, the model with key propagation is essentially relational -- while the other one is object-driven. 基本上,具有密钥传播的模型本质上是关系型的-而另一个模型是对象驱动的。 ORM tools either prefer or enforce the model with separate ID (second case), but offer other advantages for development. ORM工具更喜欢或使用具有单独ID(第二种情况)的模型,但为开发提供了其他优势。

Your example seems to be trying to use some kind of a combination of these two -- not necessarily bad, it would help if you could talk to original designer. 您的示例似乎正在尝试使用这两者的某种组合-不一定很糟糕,如果您可以与原始设计师交谈,将会很有帮助。


With key propagation 随着密钥传播

在此处输入图片说明


Independent keys for each table 每个表的独立键 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM