Я размышляю над лучшим методом обработки пользователей и учетных записей для веб-сайта.
Каждый пользователь принадлежит к одной учетной записи, у учетных записей может быть несколько пользователей. Таблицы будут 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;
Пользователи никогда не будут перемещаться из одной учетной записи в другую, поэтому учетная запись всегда будет правильной. Стоит ли дополнительным требованиям хранения данных и потерять нормализацию, чтобы удалить эти соединения из 100 других запросов, которые будет использоваться сайтом? Еще одна вещь, которую следует учитывать, заключается в том, что таблица пользователей не будет записываться на все это часто, так что маловероятно, что будут проблемы вокруг блокировки таблицы при выполнении объединений.
Наверное, нет. Я думаю, что талия хранит дополнительное поле в каждой строке, и если ваши таблицы индексируются правильно, объединение их не будет таким дорогостоящим.
Попробуйте добавить индекс в таблицу user
, чтобы включить как поля userid
, так и accountid
, так как ваша таблица - 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;
product
?