Решения структуры базы данных MySQL
Я пытаюсь выбрать между наличием 1 огромной таблицы для всех возможных данных о пользователе, многие из которых не применимы к каждому пользователю, и наличием отдельной таблицы для данных, которые пользователь может иметь несколько экземпляров (например, предыдущие работы) по сравнению с распределением данных о каждом пользователе между несколькими таблицами.
Первый способ более рационален, но я чувствую, что он будет использовать кучу ненужных накладных расходов, тогда как второй способ позволяет работать легче, но приводит к большому количеству дополнительных запросов к базе данных.
3 ответа
Несколько экземпляров некоторой связанной вещи всегда идут в другую таблицу. Этот процесс называется нормализацией.
Хотя на первый взгляд это может показаться более сложным, в долгосрочной перспективе это облегчит вашу жизнь. Системы баз данных, такие как MySQL, быстро объединяют таблицы обратно (денормализуют), если это необходимо (при условии, что ваши ключевые поля правильно проиндексированы).
Гораздо сложнее работать с денормализованными таблицами, подобными описанным вами, по ряду причин. Скажем Person
имеет более одного адреса. Как бы вы положили это в основной стол? Address1
, Address2
, Address3
? Что если у человека четыре разных адреса?
Работать с такой таблицей будет намного сложнее, потому что теперь вам приходится иметь дело с тремя столбцами в таблице, а не с одним, в каждом написанном вами запросе.
Если соответствующие качества зависят от типа пользователя, и все пользователи определенного типа имеют все эти качества, у вас может быть таблица для каждого типа.
CREATE TABLE Type1_Qualities (идентификатор int, не ноль, первичный ключ auto_increment, ссылки user_id int (пользователь), qual1 ..., qual2 ..., ...)
и аналогично для Type2 и Type3. Это позволяет избежать использования всех этих посторонних полей для каждого пользователя, но проще, чем выполнять множество объединений с общей таблицей атрибутов, такой как ответ xception.
В зависимости от того, как хранятся ваши данные, вы можете использовать структуру данных с несколькими связями, это всего лишь пример:
CREATE TABLE user (
id int not null auto_increment primary key,
name varchar[60] not null
);
CREATE TABLE attributes (
id smallint not null auto_increment primary key,
name varchar[20] not null,
order smallint --optional
);
CREATE TABLE userattributes (
user int not null references user (id),
attribute smallint not null references attributes(id),
value varchar[100] not null,
order tinyint --optional
);
INSERT INTO textattributes(name) VALUES ('alias'), ('address'), ('hobby')
Я отметил поля заказа как необязательные, так как вы можете не заботиться о тех
SELECT a.name, ua.value
FROM userattributes AS ua
JOIN attributes AS a
ON ua.attribute = a.id
WHERE user = :user
ORDER BY a.order, ua.order
Вы также можете присоединиться к пользователю, если хотите, но эти данные будут дублироваться для каждой строки, или вы можете использовать отдельный запрос для получения данных от пользователя. Я бы лично использовал для этого второй запрос.