MySQL 重复外键数据或连接?
我正在考虑处理网站用户和帐户的最佳方法。
每个用户属于一个帐户,帐户可以有多个用户。这些表将是 MyISAM,因此不存在数据库强制的引用完整性。每个用户都有权查看/添加/编辑自己的内容和/或他们所属帐户的所有用户的内容。
CREATE TABLE account (
id INT,
name VARCHAR,
... etc
);
CREATE TABLE user (
id INT,
accountId INT, // references account.id
userName,
etc.
);
数据库中几乎所有其他表都会引用用户表。例如。
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 将始终是正确的。是否值得额外的数据存储要求并失去一些规范化以从站点将使用的数百个其他查询中删除这些联接?另一件需要考虑的事情是用户表不会经常被写入,因此在进行连接时不太可能出现表锁定问题。
I'm pondering the best method to handle Users and Accounts for a website.
Every User belongs to a single Account, Accounts can have multiple Users. The tables will be MyISAM so there is no DB-enforced referential integrity. Each User will have permission to view/add/edit their own content and/or the content of all Users for the Account they are under.
CREATE TABLE account (
id INT,
name VARCHAR,
... etc
);
CREATE TABLE user (
id INT,
accountId INT, // references account.id
userName,
etc.
);
Pretty much every other table in the DB will reference the User table. Eg.
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
);
So to get products a User can access assuming the have permission to access just their own it's:
SELECT * FROM product WHERE userId = 17;
To get products a User can access when they have access to the entire account is:
SELECT p.* FROM product p, user u WHERE u.accountId = 3;
Now, the question is: Would it be better to have an accountId field in product, event etc. as well?
CREATE TABLE product (
id INT,
userId, // references user.id
accountId, // references account.id
name VARCHAR,
details TEXT
.. more stuff
);
This would remove the need for the extra join on just about every query used:
SELECT p.* FROM product p.accountId = 3;
The Users will never move from one Account to another so the accountId will always be correct. Is it worth the additonal data storage requirments and losing a bit of normalisation to remove these joins from the 100s of other queries that the site will use? One other thing to consider is that the user table will not be written to all that often so it's unlikely there will be issues around table locking while doing the joins.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可能不会。我认为它是在每一行中存储额外字段的腰部,如果你的表索引正确,连接它们不会那么昂贵。
尝试在
user
表上添加索引,以包含userid
和accountid
字段,因为您的表是 MyISAM,这将删除需要在表数据中查找accountid
。此外,您的查询 SELECT p.* FROM Product p, user u WHERE u.accountId = 3; 正在执行 OUTER join,应将其更改为
Probably not. I think its a waist storing the extra field in every row, and if your tables are indexed properly, Joining them will not be that expensive.
Try adding a index on the
user
table, to include both theuserid
and theaccountid
fields, since your table is MyISAM, that will remove the need to lookup theaccountid
in the table data.Also, your query
SELECT p.* FROM product p, user u WHERE u.accountId = 3;
is performing a OUTER join, which should be changed to