我目前正在构建一个具有多种用户类型的Web应用程序,用户可以参与多种活动类型。
我需要设计一个表格,将用户和活动之间的“喜欢”(赞成票,+ 1,等等)联系起来。无论如何我都不是不是的MySQL专家,所以我想避免使用我的数据库设计走错路,特别是这样的事情。
我在想的是如下表:
CREATE TABLE likes (
from_id int(11) NOT NULL,
from_type VARCHAR(100) NOT NULL,
to_id int(11) NULL,
to_type VARCHAR(100) NULL,
posted TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(from_id, from_type, to_id, to_type),
INDEX(from_id, from_type),
INDEX(to_id, to_type)
)Engine=InnoDB;
随着系统扩展,这会带来什么性能问题?这些“喜欢”将在新闻Feed中使用,因此会有很多的读写操作。
有没有一种我没想过的更好的方法?
提前致谢!
答案 0 :(得分:4)
你的from_type
和to_type
字段,如VARCHAR(100),将是一个巨大的空间浪费,与它们的匹配将不会像匹配,例如,整数from_type_id
和to_type_id
。当您向表中添加更多条目时,它们也会使索引的维护速度变慢。
如果您需要一个人类可读的类型名称,请创建另一个列出它们的表及其数字ID。您可以将id作为该表的外键,尽管维护外键的完整性会产生一些成本。
可能不会有太多类型,至少与表中的行数相比,所以任何需要它们的进程都可以只读取该表一次,而不是询问数据库与每次读取都进行连接。
这些将会减慢插入速度。您的目标应该是为了满足所有读取查询的要求,并尽可能地使您所做的那些查询。
多列索引肯定是有用的,并且它们具有良好的属性,即所有前缀基本上都被索引。也就是说,如果您在(a, b, c)
上有索引,那么它也可以用作(a, b)
上的索引,甚至只能用在a
上。 (并且MySQL 将以这种方式使用索引)。
这意味着,因为你有一个索引
(from_id, from_type, to_id, to_type)
然后你还需要
上的索引(to_id, to_type)
但你可以消除
上的索引(from_id, from_type)
使数据库单独维护该索引只会降低它的速度。
这也意味着您可能需要预先考虑索引中列的顺序。将type
置于id之前可能更有意义,因为您更有可能在数据库中查询特定类型的所有喜欢,而不是来自特定ID的所有喜欢(对于每种类型)。 / p>
如果您构建索引,请执行以下操作:
(to_type, to_id, from_type, from_id)
(from_type, from_id)
然后您可以有效地搜索:
(from_type)
(from_type, from_id)
发起
(to_type)
(to_type, to_id)
(to_type, to_id, from_type)
(to_type, to_id, from_type, from_id)