连接表是一个好习惯吗?

Mar*_*xou 15 mysql database-design database-size database-theory

假设我有一个包含用户信息的大表和另一个包含多个位置的表。然后我使用另一个包含 user_id 和 location_id 的表。

为了检索数据,我必须使用 Left Join 查询。与将所有内容放在一张桌子中相比,这不是使整个过程更长的检索时间吗?例如,我可以将位置作为文本放在同一张桌子上。

编辑:这是一个例子。

CREATE TABLE  `user` (
`id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `gender` enum('M','F') DEFAULT NULL
);

CREATE TABLE `user_location` (
  `user_id` int(11) NOT NULL,
  `location_id` int(11) NOT NULL
);

CREATE TABLE `location` (
`id` int(11) NOT NULL,
  `location` varchar(45),
  `parent_id` varchar(45) 
);
Run Code Online (Sandbox Code Playgroud)

注意:请假设所有相关字段都在它们之间正确索引。

编辑:我目前有一个大型数据库,用户通过如上所述的连接表检索他们的位置。我被要求优化数据库,因为搜索结果很慢。我添加了memcache它并且它有了显着的改进,但现在我只是想知道左连接。

例如,当前查询是这样的:

SELECT * FROM users 
LEFT JOIN user_location 
ON user_location.user_id = user.id 
LEFT JOIN location
ON location.id = user_location.location_id;
Run Code Online (Sandbox Code Playgroud)

这只是为了获取位置。它们还有其他几个通过联结检索的字段,并且都需要它们来查看用户的个人资料。我们的电话号码、地址、密码、出生日期和许多其他信息都在不同的表格中。

为了让我为用户配置文件创建一个页面,我必须向服务器发送一个大型查询。现在在第一次被缓存之后就可以了。但我只是想知道为什么有人会像这样构建他们的数据库?

Fed*_*oli 18

如果你把所有东西都放在一张桌子上,你就会有一张更大的、多余的桌子。

如果所有表都正确索引,3 表解决方案会很快,因为每个查询都会读取少量行。


Wal*_*tty 12

联结表是关系数据库设计中的标准做法。

如果两个实体之间存在多对多关系,则表示它们的标准方法是使用三个表。

其中两个表是实体表,带有一个主键。联结表位于它们之间(逻辑上)并包含两个外键,一个引用每个实体表。通常,这两个外键将是联结表中仅有的两列。


Ric*_*mes 9

“请假设所有相关字段都在它们之间正确索引。” 不,我不会那样做。我看到太多用户从未听说过“复合”索引,更不用说了解它们的重要性了。

特别是,您应该:

CREATE TABLE user_location(
    # No surrogate id for this table
    user_id     MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to one table
    location_id MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to the other table
    # Include other fields specific to the 'relation'
    PRIMARY KEY(user_id, location_id),            -- When starting with user
    INDEX      (location_id, user_id)             -- When starting with location
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)

进一步的笔记在我的博客中