在此上下文中使用复合主键而不是单个主键有什么好处?

时间:2015-04-29 09:37:11

标签: mysql cakephp database-design primary-key composite-primary-key

Cakephp v3现在能够支持复合主键。 http://book.cakephp.org/3.0/en/quickstart.html

快速入门指南中给出的一个例子;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created DATETIME,
    modified DATETIME
);

CREATE TABLE bookmarks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(50),
    description TEXT,
    url TEXT,
    created DATETIME,
    modified DATETIME,
    FOREIGN KEY user_key (user_id) REFERENCES users(id)
);

CREATE TABLE tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    created DATETIME,
    modified DATETIME,
    UNIQUE KEY (title)
);

CREATE TABLE bookmarks_tags (
    bookmark_id INT NOT NULL,
    tag_id INT NOT NULL,
    PRIMARY KEY (bookmark_id, tag_id),
    INDEX tag_idx (tag_id, bookmark_id),
    FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
    FOREIGN KEY bookmark_key(bookmark_id) REFERENCES bookmarks(id)
);

快速入门指南提到了"You may have noticed that the bookmarks_tags table used a composite primary key. CakePHP supports composite primary keys almost everywhere, **making it easier to build multi-tenanted applications**."

多租户申请是什么意思?在这种情况下,为什么使用复合主键与单主键更好?

3 个答案:

答案 0 :(得分:5)

简而言之:clustering

InnoDB将使用相同的bookmarks_tags自动聚集(物理组合在一起)bookmark_id行,使某些查询 1 非常快,因为DBMS不必“跳转”在整个表格中收集所有相关的行。

在这种情况下,不需要代理键(自动增量int),也不需要为其基础索引支付的额外价格。有关自然密钥和代理密钥的更全面讨论,请查看here

虽然我不熟悉Cakephp v3,但我猜它们只是意味着您可以使用租户ID为所有表的键添加前缀,并且由于聚类而在性能方面支付很少。

1 例如:“查找给定书签的标签”。由于您还有{tag_id, bookmark_id}的索引,相反的查询:“查找给定标记的书签”也会很快。

答案 1 :(得分:3)

多租户正在保留几个不同的组织'数据在同一个数据库中,但是以一种使数据在逻辑上彼此分离的方式。对于有许多客户使用一个通用应用程序的系统提供商来说,这是一种常见的方法。

您引用的CakePHP文档中评论的重要性在于,他们希望您将多个组织隔离开来。通过在每个表格的主键中添加org_id之类的内容,在一组表格中设置(租户')数据。

当然,在单个用户系统的上下文中使用复合主键还有其他原因,但很明显,CakePHP在添加此功能时会考虑多租户支持。

答案 2 :(得分:-1)

如果我们执行select * from bookmarks_tags,则排序将根据表bookmarks_id(first field)的列bookmarks_tags完成。