【问题标题】:User rating - sql schema optimization用户评分 - sql 架构优化
【发布时间】:2015-02-25 15:24:26
【问题描述】:

我有一个用户等级数据模式的小草图:

CREATE TABLE user 
    (
     user_id int auto_increment primary key, 
     nickname varchar(50), 
     details varchar(30)
    );

CREATE TABLE rank 
    (
     rank_id int auto_increment primary key, 
     level int,
     type varchar(20) 
    );

CREATE TABLE user_rank
    (
      user_id int auto_increment not null,
      rank_id int auto_increment not null,
      FOREIGN KEY (user_id) REFERENCES user(user_id),
      FOREIGN KEY (rank_id) REFERENCES rank(rank_id),
    );


INSERT INTO user
(nickname, details)
VALUES
('Horax', 'admin@sqlfiddle.com'),
('Goan', '@sqlfiddle');

INSERT INTO rank
(level, type)
VALUES
(10, 'bronze'),
(15, 'gold');

INSERT INTO user_rank
(user_id, rank_id)
VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4);

我想选择 (a) N 个评分最高的用户,(b) 在任何时候通过 user_id 快速获取用户昵称和用户详细信息,数据量为 100 万条记录:

SELECT * FROM user_rank LEFT JOIN user ON user_rank.user_id = user.user_id
LEFT JOIN rank ON rank.rank_id = user_rank.rank_id 
ORDER by level DESC
LIMIT N

SELECT user.nickname, user.details FROM user_rank LEFT JOIN user ON user_rank.user_id = user.user_id
LEFT JOIN rank ON rank.rank_id = user_rank.rank_id 
WHERE user.user_id = 10

如何调整此架构和查询以提高性能?你看到了哪些薄弱环节?

感谢您的帮助,同事们!

【问题讨论】:

  • 如果您选择的只是基于 user_id 的用户字段,为什么还要在第二个查询中加入任何内容?

标签: mysql sql postgresql relational-database query-optimization


【解决方案1】:

你最终会有多少行?

这是一个经典的多对多关系表,对吗?它不会起作用,而且效率极低。改成这样:

CREATE TABLE user_rank (
    user_id int not null,
    rank_id int not null,
    PRIMARY KEY(user_id, rank_id),
    INDEX(rank_id, user_id)
) ENGINE=InnoDB;

(如果您愿意,请重新添加 FOREIGN KEY。)

rank 中,您同时拥有rank_idlevel。如果 level 在表中是唯一的,则将其设为 PRIMARY KEY 并删除 rank_id(并将其他引用更改为 rank_id)。

这些更改应该可以很好地为您服务到数百万行。

如果一个用户没有很多级别,那么摆脱桌子!只需将level 放入user 表中(并去掉rank_id)。

【讨论】:

  • 感谢您的回答!我唯一的问题是如何优化对该方案的查询?我在消息正文中提到的查询是否最适合该方案?
  • (我添加到“答案”)
  • 我没有注意到任何变化,抱歉。
  • 如果一个用户没有很多级别,那么就摆脱桌子!只需将级别放入用户表(并摆脱 rank_id)。
猜你喜欢
  • 1970-01-01
  • 2017-09-13
  • 2017-02-05
  • 2017-06-29
  • 2013-05-11
  • 2018-03-02
  • 2017-10-23
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多