如何设计一个简单高效的MySQL黑名单表

时间:2018-01-24 16:49:40

标签: mysql sql database

假设我有一个用户表my_users,其中有一个主键id。另外,我希望设计一个简单的黑名单表(在MySQL中),其声明如下:

CREATE TABLE IF NOT EXISTS black_list (
  user_id INT NOT NULL,
  bad_string VARCHAR(100) NOT NULL,
  FOREIGN KEY (user_id) REFERENCES my_users(id),
  PRIMARY KEY (user_id, bad_string));

black_list中任何行的解释是ID为user_id的用户想要将字符串bad_string列入黑名单。显然,user_id不能是唯一的,因为单个用户可能有多个列入黑名单的字符串。换句话说,bad_string不能是唯一的,因为多个用户可能会将相同的字符串列入黑名单。但是,该对(user_idbad_string)应该是唯一的,因为用户不会多次将相同的字符串列入黑名单。

在最糟糕的情况下,当我们通过用户ID(SELECT * FROM black_list WHERE user_id = X)选择黑名单时,MySQL必须扫描整个black_list表。

我的问题是:有没有办法在次线性时间内运行SELECT语句,关于black_list表中的行数?如果是,我该如何实现?

1 个答案:

答案 0 :(得分:2)

SELECT * FROM black_list WHERE user_id = X必须扫描整个black_list表的断言不正确。

在此sql fiddle中,您可以看到它正在使用索引:

+----+-------------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type |   table    | type | possible_keys |   key   | key_len |  ref  | rows | filtered |    Extra    |
+----+-------------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | black_list | ref  | PRIMARY       | PRIMARY |       4 | const |    1 |   100.00 | Using index |
+----+-------------+------------+------+---------------+---------+---------+-------+------+----------+-------------+