【发布时间】: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