2016-11-23 2 views
-2

Я работаю над приложением, которое ранее имело уникальные ручки только для пользователей, но теперь мы хотим иметь дескрипторы для событий, групп, мест ... и т. Д. Уникальные идентификаторы строк для многих объектов первого класса. Я понимаю, что нужно что-то предпринять, это принять что-то вроде Партийной модели, где каждая сущность имеет свой собственный уникальный идентификатор partyId и дескриптор. Тем не менее, это означает, что почти каждый запрос на выборку данных мы добавляем соединение, чтобы получить этот дескриптор! Конечно для каждого пользователя.В чем именно заключается потеря производительности при добавлении таблицы, которая объединяется по каждому запросу?

Итак, какова потеря производительности здесь? Для таблицы с тремя или четырьмя столбцами, это соединение, как это ничтожно? Или есть лучший способ обойти это?

Пример структуры таблицы:

Party 
    int id 
    int party_type_id 
    varchar(256) handle 

Events 
    int id 
    int party_id 
    varchar(256) name 
    varchar(256) time 
    int place_id 

Users 
    int id 
    int party_id 
    varchar(256) first_name 
    varchar(256) last_name 

Places 
    int id 
    int party_id 
    varchar(256) name 

- EDIT -

Я получаю плохую оценку по этому вопросу, и я не уверен, я понимаю, почему. В PLAIN TERMS, я спрашиваю:

Если у меня есть три объекта первого класса, которые должны совместно использовать свойство UNIQUE HANDLE, уникальное по всем трем объектам, добавляет дополнительную таблицу, к которой нужно подключиться практически по любому запросу значительный успех? Есть ли лучший способ сделать это в реляционной базе данных, например MySQL?

- EDIT: Предлагаемые запросы -

Попадая один пользователь

SELECT * FROM Users u LEFT JOIN Party p ON u.party_id = p.id WHERE p.handle='foo' 

Поиск пользователей

SELECT * FROM Users u LEFT JOIN Party p ON u.party_id = p.id WHERE p.handle LIKE '%foo%' 

Поиск всех сторон ... Я думаю, я не уверен, как это сделать в одном запросе. Вам нужно будет выбрать все Стороны, соответствующие дескриптору, а затем получить отдельные объекты в отдельных запросах? Например.

db.makeQuery(SELECT * FROM Party p WHERE p.handle LIKE '%foo%') 
.then(function (results) { 
    // iterate through results and assemble lists of matching parties by type, then get those objects in separate queries 
}) 

Этот последний пример - это то, что меня больше всего волнует, я думаю. Это разумный дизайн?

+2

Соединение должно быть выполнено, если все поля объединения проиндексированы. Вы должны использовать 'EXPLAIN' для обнаружения оптимизаций для сложных запросов на соединение: http://dev.mysql.com/doc/refman/5.7/en/using-explain.html – leepowers

+0

Неясно, из вашего вопроса, что вы пытаетесь достичь, и какие варианты вы придумали, но. Если вопрос о структуре БД и использование второй или третьей формы нормализации, лучше использовать третью.присоединение к первичному ключу не сильно повлияет на вашу производительность, но добавление столбцов, таких как option_title, option_title2, усложнит вашу логику. – 2oppin

+0

Можете ли вы объяснить, что вы подразумеваете под «второй или третьей формой нормализации»? – tcmoore

ответ

1

Запросы, которые вы показываете, должны быть невероятно быстрыми в любой современной реализации и должны иметь размеры до десятков или сотен тысяч миллионов записей без особых проблем.

Реляционные системы управления базами данных (из которых один MySQL) специально разработаны для этого сценария.

В самом деле, медленная часть вашего второго запроса:

SELECT * FROM Users u LEFT JOIN Party p ON u.party_id = p.id WHERE p.handle LIKE '%foo%' 

будет WHERE p.handle LIKE '%foo%', поскольку это не будет иметь возможность использовать индекс. Когда у вас будет большая таблица, эта часть запроса будет во много раз медленнее, чем соединение.

+0

Как насчет возврата результатов поиска через другие таблицы? Может ли это быть сделано в одном запросе, или я прав, думая, что их нужно будет отделить после первоначального поиска на вечеринке? – tcmoore