2014-02-10 47 views
2

有一个表包含比真实数据数据更多的id数据。带有多列的MySQL InnoDB主键

user_id int unsigned NOT NULL, 
project_id int unsigned NOT NULL, 
folder_id int unsigned NOT NULL, 
file_id int unsigned NOT NULL, 
data TEXT NOT NULL 

创建此表的唯一主密钥将是一个复合的唯一方法(USER_ID,PROJECT_ID,folder_id,FILE_ID)。我经常看到2列复合主键,但可以有4个或更多?根据MySQL:“所有存储引擎每个表至少支持16个索引,索引总长度至少为256字节,大多数存储引擎都有更高的限制”,所以我知道至少可以这样做。

过去,对于这些ID的各种组合,这个表格经常被查询。例如,找到用户X的所有项目,查找用户X的所有文件,查找项目Y和文件夹Z的所有文件等。如果每个ID列上都有一个单独的索引键,或者存在复合已包含所有列的主键是否会使更多个别密钥变得冗余?桌面上随时会有大约1000万到5000万行。

总结:有一个带有4个(或更多)id列的组合主键是否可以,并且如果有一个组合键,是否会为每个列创建额外的单独键?

+0

据我所知,没有什么能够让n-column主键成为一个坏主意,只要它有助于保持数据正常化。除此之外,我会为那些将会出现最多“where”条件的字段创建单独的索引。 – Barranka

回答

2

是的,可以有一个4列或更多列的复合主键。

它并不一定会为每个列创建额外的密钥。例如,对于查询SELECT ... WHERE b = 4key (a, b, c)将不会有用。对于这种类型的查询,你宁愿有key (b)key (b, c)

您需要检查预期的查询以确定需要哪些索引。请参阅此讲座以获取更多详细信息:http://youtu.be/AVNjqgf7zNw

1

是的,如果数据模型支持它,那么这是可以的。您尚未分享太多有关整体数据库架构以及这些项目如何相互关联以确定这是否可被视为最佳方法的信息。换句话说,这是真正实现这些项目相互关联的唯一方式,或者例如是与项目和用户相关的项目或类似项目的真实相关的文件,例如分割这些连接表使逻辑更加合理。

如果您正在查询此主键中的各个列,这可能表明您的模式不完全正确。至少您可能需要在这些列上添加单独的索引以支持此类查询。

+0

与单独列上的索引相比,更有可能需要使用不同顺序的列的更多复合索引:但是,这当然取决于人们希望执行的精确查询。 – eggyal

+0

@eggyal绝对如此。理解访问模式在这里很重要,在评估时可能表明不同的模式更合适。 –

0

你会后悔创建一个复合主键,它将变得非常令人讨厌,因为在MySQL中必须包含作为行标识符的主键。不过,您可以创建一个UNIQUE这是复合。

您可以使用组合键数量相当多的组合键,但请记住,您添加得越多,索引将获得的值越大,并且在执行INSERT时的更新速度就会越慢。随着数据库规模的增长,插入操作可能会变得非常缓慢。

这就是为什么,只要有可能,你应该尽量减少索引大小。

+0

我认为这个答案可能需要至少一点资格:例如,如果构成列的共域的笛卡尔乘积内的每个可能值都存在(在大多数现实世界情景中不太可能),则将一个4 x 4字节的化合物值不会比任何其他可能设计的PK更差(在索引尺寸或性能方面)。 – eggyal

+0

没有人在数据库中存储几十亿个数字,它只是没有发生。这个数字是如此愚蠢的巨大,没有电脑会存储那么多的数据。请记住,更大的PK会导致更大的索引。保持你的PK尽可能小。除非你确实需要'BIGINT',否则'INT'更可取。 – tadman

+0

够公平的。 FWIW,我没有downvote。 – eggyal