【问题标题】:MySQL duplicate foreign key data or joins?MySQL重复外键数据或连接?
【发布时间】:2011-06-10 05:42:31
【问题描述】:

我正在考虑处理网站用户和帐户的最佳方法。

每个用户都属于一个帐户,帐户可以有多个用户。这些表将是 MyISAM,因此没有 DB 强制引用完整性。每个用户都有权查看/添加/编辑他们自己的内容和/或他们所在帐户的所有用户的内容。

CREATE TABLE account (
id INT,
name VARCHAR,
... etc
);

CREATE TABLE user (
id INT,
accountId INT, // references account.id
userName,
etc.
);

数据库中几乎所有其他表都将引用 User 表。例如。

CREATE TABLE product (
id INT,
userId, // references user.id
name VARCHAR,
details TEXT
.. more stuff
);

CREATE TABLE event (
id INT,
userId INT,
name VARCHAR,
date DATETIME,
..etc
);

所以要获得用户可以访问的产品,假设他们有权访问自己的产品:

SELECT * FROM product WHERE userId = 17;

要获得用户在有权访问整个帐户时可以访问的产品:

SELECT p.* FROM product p, user u WHERE u.accountId = 3;

现在的问题是:在产品、事件等中也有一个 accountId 字段会更好吗?

CREATE TABLE product (
id INT,
userId, // references user.id
accountId, // references account.id
name VARCHAR,
details TEXT
.. more stuff
);

这将消除对几乎每个使用的查询的额外连接的需要:

SELECT p.* FROM product p.accountId = 3;

用户永远不会从一个帐户移动到另一个帐户,因此 accountId 将始终正确。从站点将使用的 100 多个其他查询中删除这些连接是否值得额外的数据存储要求并失去一些规范化?要考虑的另一件事是,用户表不会经常被写入所有内容,因此在执行连接时不太可能出现表锁定问题。

【问题讨论】:

  • 如果代码缺陷使产品属于用户 A 和组 B,但用户 A 不在组 B 中,会有多糟糕?
  • product 表的读写比例是多少?
  • 如果某些东西属于用户和不相关的帐户,在特定情况下可能会非常糟糕..
  • 我不确定这个比例是多少,但阅读频率会更高。可能在至少 1000:1 读取到写入的范围内。

标签: mysql normalization denormalization


【解决方案1】:

可能不会。我认为在每一行中存储额外的字段是一个腰部,如果您的表被正确索引,加入它们不会那么昂贵。

尝试在user 表上添加索引,以包括useridaccountid 字段,因为您的表是MyISAM,这将消除在表数据中查找accountid 的需要。

另外,您的查询 SELECT p.* FROM product p, user u WHERE u.accountId = 3; 正在执行 OUTER 联接,应将其更改为

SELECT p.*
FROM product p JOIN user u ON p.userid = u.id
WHERE u.accountId = 3;

【讨论】:

  • 感谢您的 cmets。我已经在那里找到了索引,只是想知道我是不是走错了路。
  • 其实不是,不是复合键。在这种情况下有什么好处?无论如何,我需要一个 accountid 索引来进行其他查找。
  • @fred 创建一个包含这两个字段的附加索引。阅读dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
猜你喜欢
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 2014-04-02
  • 2011-12-26
  • 2016-07-04
  • 2020-12-29
相关资源
最近更新 更多