MySQL重复外键数据或连接?

时间:2011-01-17 03:36:38

标签: mysql normalization denormalization

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

每个用户都属于一个帐户,帐户可以拥有多个用户。这些表将是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个查询中删除这些连接?另一件需要考虑的事情是,用户表不会经常写入所有用户表,因此在进行连接时,表锁定不太可能出现问题。

1 个答案:

答案 0 :(得分:0)

可能不是。我认为它的腰部存放着每一行中的额外字段,如果你的表格被正确编入索引,加入它们就不会那么贵了。

尝试在user表上添加索引,以包含useridaccountid字段,因为您的表格是MyISAM,这样就无需查找accountid 1}}在表数据中。

此外,您的查询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;