MySQL дублирует данные внешнего ключа или присоединяет?

0

Я размышляю над лучшим методом обработки пользователей и учетных записей для веб-сайта.

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

  • 0
    Насколько было бы плохо, если бы из-за недостатка кода продукт принадлежал пользователю A и группе B, но пользователь A не входит в группу B?
  • 0
    Что такое соотношение чтения и записи для таблицы product ?
Показать ещё 2 комментария
Теги:
denormalization
normalization

1 ответ

0

Наверное, нет. Я думаю, что талия хранит дополнительное поле в каждой строке, и если ваши таблицы индексируются правильно, объединение их не будет таким дорогостоящим.

Попробуйте добавить индекс в таблицу 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;
  • 0
    Спасибо за ваши комментарии. У меня там уже есть индексы, мне просто интересно, пойду ли я по этому поводу неправильно.
  • 0
    @fred У вас уже есть составной индекс?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню